<!DOCTYPE html>
<html  lang="zh">
<head>
    <meta charset="utf-8">
<title>图片合成支持的前世今生 - 一灰灰Blog</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />



    <meta name="description" content="图片合成的前世今生 作为一个后端，为什么要做图片合成？为什么要实现类xml标记语言的渲染？  本片博文准备详细的记录一下，一个java后端如何去支持图片合成，在这个过程中采用了哪些猥琐的方案，又遇到了哪些鬼畜的问题">
<meta name="keywords" content="手记">
<meta property="og:type" content="article">
<meta property="og:title" content="图片合成支持的前世今生">
<meta property="og:url" content="https://blog.hhui.top/hexblog/2017/12/17/图片合成支持的前世今生/index.html">
<meta property="og:site_name" content="一灰灰Blog">
<meta property="og:description" content="图片合成的前世今生 作为一个后端，为什么要做图片合成？为什么要实现类xml标记语言的渲染？  本片博文准备详细的记录一下，一个java后端如何去支持图片合成，在这个过程中采用了哪些猥琐的方案，又遇到了哪些鬼畜的问题">
<meta property="og:locale" content="zh-CN">
<meta property="og:image" content="https://blog.hhui.top/hexblog/images/og_image.png">
<meta property="og:updated_time" content="2018-07-25T14:55:41.000Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="图片合成支持的前世今生">
<meta name="twitter:description" content="图片合成的前世今生 作为一个后端，为什么要做图片合成？为什么要实现类xml标记语言的渲染？  本片博文准备详细的记录一下，一个java后端如何去支持图片合成，在这个过程中采用了哪些猥琐的方案，又遇到了哪些鬼畜的问题">
<meta name="twitter:image" content="https://blog.hhui.top/hexblog/images/og_image.png">







<link rel="icon" href="/hexblog/images/avatar.jpg">


<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.7.2/css/bulma.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:400,600|Source+Code+Pro">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@9.12.0/styles/docco.css">


    
    
    
    <style>body>.footer,body>.navbar,body>.section{opacity:0}</style>
    

    
    
    
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lightgallery@1.6.8/dist/css/lightgallery.min.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/justifiedGallery@3.7.0/dist/css/justifiedGallery.min.css">
    

    
    

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/outdatedbrowser@1.1.5/outdatedbrowser/outdatedbrowser.min.css">


    
    
    
    

<link rel="stylesheet" href="/hexblog/css/back-to-top.css">


    
    

    
    
<script>
var _hmt = _hmt || [];
(function() {
    var hm = document.createElement("script");
    hm.src = "//hm.baidu.com/hm.js?028d9e53f991d9739ecc7cc42e13c500";
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(hm, s);
})();
</script>

    
    

    
    
<link rel="stylesheet" href="/hexblog/css/progressbar.css">
<script src="https://cdn.jsdelivr.net/npm/pace-js@1.0.2/pace.min.js"></script>

    
    
    

    
    
    


<link rel="stylesheet" href="/hexblog/css/style.css">
</head>
<body class="is-3-column">
    <nav class="navbar navbar-main">
    <div class="container">
        <div class="navbar-brand is-flex-center">
            <a class="navbar-item navbar-logo" href="/hexblog/">
            
                <img src="/hexblog/images/avatar.jpg" alt="图片合成支持的前世今生" height="28">
            
            </a>
        </div>
        <div class="navbar-menu">
            
            <div class="navbar-start">
                
                <a class="navbar-item"
                href="/hexblog/.">首页</a>
                
                <a class="navbar-item"
                href="/hexblog/archives">归档</a>
                
                <a class="navbar-item"
                href="/hexblog/tags">标签</a>
                
                <a class="navbar-item"
                href="http://spring.hhui.top">Spring</a>
                
                <a class="navbar-item"
                href="/hexblog/categories/Java/">Java</a>
                
                <a class="navbar-item"
                href="/hexblog/categories/Python/">Python</a>
                
                <a class="navbar-item"
                href="/hexblog/categories/DB/">DB</a>
                
                <a class="navbar-item"
                href="/hexblog/categories/Shell/">Shell</a>
                
                <a class="navbar-item"
                href="/hexblog/categories/Quick系列/">Quick系列</a>
                
                <a class="navbar-item"
                href="/hexblog/categories/前端/">前端</a>
                
                <a class="navbar-item"
                href="/hexblog/categories/开源/">开源</a>
                
                <a class="navbar-item"
                href="/hexblog/categories/工具/">工具</a>
                
                <a class="navbar-item"
                href="/hexblog/categories/随笔/">随笔</a>
                
                <a class="navbar-item"
                href="/hexblog/about">关于</a>
                
            </div>
            
            <div class="navbar-end">
                
                    
                    
                    <a class="navbar-item" target="_blank" title="Download on GitHub" href="https://github.com/liuyueyi">
                        
                        <i class="fab fa-github"></i>
                        
                    </a>
                    
                
                
                
                <a class="navbar-item search" title="搜索" href="javascript:;">
                    <i class="fas fa-search"></i>
                </a>
                
            </div>
        </div>
    </div>
</nav>
    
    <section class="section">
        <div class="container">
            <div class="columns">
                <div class="column is-8-tablet is-8-desktop is-7-widescreen has-order-2 column-main"><div class="card">
    
        <span >
            <div class="thumbnail default_logo">
                <br/>
                <span >
                图片合成支持的前世今生
                <br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                <span style="font-size:0.7em">by 一灰灰</span>
                </span>
            </div>
            </span>
    

    <div class="card-content article ">
        
        <div class="level article-meta is-size-7 is-uppercase is-mobile is-overflow-x-auto">
            <div class="level-left">
                <time class="level-item has-text-grey" datetime="2017-12-17T09:50:31.000Z">2017-12-17</time>
                
                <div class="level-item">
                <a class="has-link-black -link" href="/hexblog/categories/随笔/">随笔</a>&nbsp;/&nbsp;<a class="has-link-black -link" href="/hexblog/categories/随笔/吐槽/">吐槽</a>
                </div>
                
                
                <span class="level-item has-text-grey" style='font-size: 1.2em;'>
                    
                    
                    1 小时 读完 (大约 6752 个字)
                </span>
                
                
                
                <span class="level-item has-text-grey" id="busuanzi_container_page_pv">
                    <i class="far fa-eye"></i>
                    <span id="busuanzi_value_page_pv">0</span>次访问
                </span>
                
            </div>
        </div>
        
        <h1 class="title is-size-3 is-size-4-mobile has-text-weight-normal">
            
                图片合成支持的前世今生
            
        </h1>
        <div class="content">
            
                <!-- 文章详情页 -->
                <div id="toc" class="toc-article">
                <strong class="toc-title"> 文章目录 </strong>
                    <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#图片合成的前世今生"><span class="toc-text">图片合成的前世今生</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#I-背景"><span class="toc-text">I. 背景</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#0-无聊的技术研究"><span class="toc-text">0. 无聊的技术研究</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-蛋疼的小程序"><span class="toc-text">1. 蛋疼的小程序</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-开动"><span class="toc-text">2. 开动</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#II-技术尝试"><span class="toc-text">II. 技术尝试</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#0-java的html渲染库"><span class="toc-text">0. java的html渲染库</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#a-html2image"><span class="toc-text">a. html2image</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#b-xhtml渲染包"><span class="toc-text">b. xhtml渲染包</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#c-借助转pdf的包"><span class="toc-text">c. 借助转pdf的包</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#d-小结"><span class="toc-text">d. 小结</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-imagemagic的合成"><span class="toc-text">1. imagemagic的合成</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#a-环境准备"><span class="toc-text">a. 环境准备</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#b-java调用"><span class="toc-text">b. java调用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#c-其他一些不得不说的故事"><span class="toc-text">c. 其他一些不得不说的故事</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-awt的绘制"><span class="toc-text">2. awt的绘制</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#o-接口定义"><span class="toc-text">o. 接口定义</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#a-图片-：-ImgBO"><span class="toc-text">a. 图片 ： ImgBO</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#b-文字：FontBO"><span class="toc-text">b. 文字：FontBO</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#c-直线-LineBO"><span class="toc-text">c. 直线: LineBO</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#d-矩形：-RoundRectBO"><span class="toc-text">d. 矩形： RoundRectBO</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#e-纯色：-ColorBgBO"><span class="toc-text">e. 纯色： ColorBgBO</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#小结-amp-问题"><span class="toc-text">小结&amp;问题</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-html-转-图片"><span class="toc-text">3. html 转 图片</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#a-环境准备-1"><span class="toc-text">a. 环境准备</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#b-实测"><span class="toc-text">b. 实测</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#c-分析小结"><span class="toc-text">c. 分析小结</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#d-chrome-方式"><span class="toc-text">d. chrome 方式</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-svg-转-图片"><span class="toc-text">4. svg 转 图片</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#a-依赖整理"><span class="toc-text">a. 依赖整理</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#b-实测-1"><span class="toc-text">b. 实测</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#c-问题"><span class="toc-text">c. 问题</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#III-最后收尾"><span class="toc-text">III. 最后收尾</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-吐槽"><span class="toc-text">1. 吐槽</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-小结"><span class="toc-text">2. 小结</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#III-其他"><span class="toc-text">III. 其他</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#体验网址"><span class="toc-text">体验网址</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#个人博客：-一灰灰Blog"><span class="toc-text">个人博客： 一灰灰Blog</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#声明"><span class="toc-text">声明</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#扫描关注"><span class="toc-text">扫描关注</span></a></li></ol></li></ol>
                </div>
            

            <h2 id="图片合成的前世今生"><a href="#图片合成的前世今生" class="headerlink" title="图片合成的前世今生"></a>图片合成的前世今生</h2><blockquote>
<p>作为一个后端，为什么要做图片合成？为什么要实现类xml标记语言的渲染？</p>
</blockquote>
<p>本片博文准备详细的记录一下，一个java后端如何去支持图片合成，在这个过程中采用了哪些猥琐的方案，又遇到了哪些鬼畜的问题</p>
<a id="more"></a>
<h2 id="I-背景"><a href="#I-背景" class="headerlink" title="I. 背景"></a>I. 背景</h2><h3 id="0-无聊的技术研究"><a href="#0-无聊的技术研究" class="headerlink" title="0. 无聊的技术研究"></a>0. 无聊的技术研究</h3><p>最开始萌发支持图片合成的想法，那时候还是在做二维码的时候，用了一些awt的画图工具，感觉还挺有意思的，这是一个和当前的电商主流完全不搭边的技术分支，开始用的时候感慨，这东西牛逼了，什么都可以干（虽然操作非常不友好），再加上用到有道云，它的会员功能支持加功能将笔记以图片方式生成，所以就有个想法，java后端能不能支持markdown输出图片呢？</p>
<h3 id="1-蛋疼的小程序"><a href="#1-蛋疼的小程序" class="headerlink" title="1. 蛋疼的小程序"></a>1. 蛋疼的小程序</h3><p>不是一个专业的小程序开发者，虽然写过一个小程序，但是很多特性依然不知道；</p>
<p>突然很多前端突然提了这么一个需求，要求后端支持图片合成，用于分享到朋友圈</p>
<p>至于原因:</p>
<ul>
<li>有的说小程序没有提供截屏接口</li>
<li>小程序不支持绘图（这个我不太确定真实性）</li>
<li>小程序绘图的api不可控（如果他们有bug，我们就没法玩了；对此我的看法是，你整个东西都是在小程序的体系里了，要是有个严重bug，那我们的小程序干脆就不玩好了…）</li>
<li>前端这么多，每个人都去绘制一遍低效，有个后端通用的，各个平台都释放了，都可以直接用… (对此我也没啥好说的，如果我是前端我也挺这一点；然而我不是，所以我拒绝😢)</li>
</ul>
<p><strong>声明</strong></p>
<p>上面括号的内容纯粹是个人吐槽，没有任何偏向性，</p>
<h3 id="2-开动"><a href="#2-开动" class="headerlink" title="2. 开动"></a>2. 开动</h3><p>有需求了，就必须去支持了，而且从技术角度出发，这是一个非常有意思的点，新的挑战，可以一试</p>
<h2 id="II-技术尝试"><a href="#II-技术尝试" class="headerlink" title="II. 技术尝试"></a>II. 技术尝试</h2><p>为了支持这个需求，尝试了不少的手段，接下来一一说明，当然由于个人见识有限，最终选择的也不一定是啥好东西，目前也只是处于可用的状态，离友好支持，还比较遥远</p>
<h3 id="0-java的html渲染库"><a href="#0-java的html渲染库" class="headerlink" title="0. java的html渲染库"></a>0. java的html渲染库</h3><blockquote>
<p>最先想到的就是这个，有没有直接可以渲染的库，大Java号称是在github上拥有最多开源工具的语言</p>
</blockquote>
<p>查了一些开源库，也主动去尝试过一些，下面给出使用姿势</p>
<h4 id="a-html2image"><a href="#a-html2image" class="headerlink" title="a. html2image"></a>a. html2image</h4><p>直接在Github上搜，找一个最多star的就可以了，测试的框架 </p>
<ul>
<li><a href="https://github.com/hkirk/java-html2image" target="_blank" rel="noopener">java-html2image</a></li>
</ul>
<p>接入及测试方式</p>
<p>pmo 依赖引入</p>
<figure class="highlight xml hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>gui.ava<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>html2image<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>0.9<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">repositories</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">repository</span>&gt;</span></span><br><span class="line">        <span class="hljs-tag">&lt;<span class="hljs-name">id</span>&gt;</span>yoava<span class="hljs-tag">&lt;/<span class="hljs-name">id</span>&gt;</span></span><br><span class="line">        <span class="hljs-tag">&lt;<span class="hljs-name">name</span>&gt;</span>AOL yoava<span class="hljs-tag">&lt;/<span class="hljs-name">name</span>&gt;</span></span><br><span class="line">        <span class="hljs-tag">&lt;<span class="hljs-name">url</span>&gt;</span>http://yoava.artifactoryonline.com/yoava/repo<span class="hljs-tag">&lt;/<span class="hljs-name">url</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;/<span class="hljs-name">repository</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">repositories</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>测试代码也比较简单</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-meta">@Test</span></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">testRenderHtml</span><span class="hljs-params">()</span> </span>&#123;</span><br><span class="line">    String url = <span class="hljs-string">"http://www.baidu.com"</span>;</span><br><span class="line">    HtmlImageGenerator generator = <span class="hljs-keyword">new</span> HtmlImageGenerator();</span><br><span class="line">    generator.loadUrl(url);</span><br><span class="line"></span><br><span class="line">    BufferedImage img = generator.getBufferedImage();</span><br><span class="line">    System.out.println(<span class="hljs-string">"---"</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>接下来就是看输出的图片了，看下是否和我们预期相同</p>
<p><img src="http://s2.mogucdn.com/mlcdn/c45406/171217_3e12a2he6598kcj107cld089e699j_935x418.png" alt="html2img.png"></p>
<p>这个颜色，样式有点鬼畜，折腾了一番，实际验证这个框架挺不错的，就是有以下几个问题</p>
<ul>
<li>很久很久很久很久很久以前的产物了</li>
<li>没人维护</li>
<li>css样式支持不友好</li>
</ul>
<p>换个复杂点的url，比如淘宝or蘑菇街商品详情页，返回就更鬼畜了，有兴趣的童鞋可自己尝试一下</p>
<h4 id="b-xhtml渲染包"><a href="#b-xhtml渲染包" class="headerlink" title="b. xhtml渲染包"></a>b. xhtml渲染包</h4><p>这个也可以实现html渲染，又是一个老古董级别的东西，已经忘记从哪里捞出来的，最初实现markdown渲染成图片，就是采用的这个包，对简单的css的支持还算友好</p>
<p>pom依赖</p>
<figure class="highlight xml hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">&lt;!--html to image render--&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.xhtmlrenderer<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>core-renderer<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>R8<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>net.sourceforge.nekohtml<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>nekohtml<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.9.14<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line"><span class="hljs-comment">&lt;!--html to image render--&gt;</span></span><br></pre></td></tr></table></figure>
<p>测试case</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-meta">@Test</span></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">testRender</span><span class="hljs-params">()</span> </span>&#123;</span><br><span class="line">    <span class="hljs-keyword">try</span> &#123;</span><br><span class="line">        String url = <span class="hljs-string">"http://www.baidu.com"</span>;</span><br><span class="line">        BufferedImage buf = ImageRenderer.renderToImage(url, <span class="hljs-string">"/Users/yihui/html2image.pdf"</span>, <span class="hljs-number">800</span>);</span><br><span class="line">        System.out.println(<span class="hljs-string">"---"</span>);</span><br><span class="line">    &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;</span><br><span class="line">        e.printStackTrace();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>使用起来还是比较简单的，但是，上面这种直接执行，会抛异常，说访问的html有些语法有问题; 然后做了一些修改和调整，修正后的测试代码</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> DOMParser domParser;</span><br><span class="line"></span><br><span class="line"><span class="hljs-keyword">static</span> &#123;</span><br><span class="line">    domParser = <span class="hljs-keyword">new</span> DOMParser(<span class="hljs-keyword">new</span> HTMLConfiguration());</span><br><span class="line">    <span class="hljs-keyword">try</span> &#123;</span><br><span class="line">        domParser.setProperty(<span class="hljs-string">"http://cyberneko.org/html/properties/names/elems"</span>, <span class="hljs-string">"lower"</span>);</span><br><span class="line">    &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;</span><br><span class="line">        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RuntimeException(<span class="hljs-string">"Can't create HtmlParserImpl"</span>, e);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">private</span> Document <span class="hljs-title">parseDocument</span><span class="hljs-params">(String content)</span> <span class="hljs-keyword">throws</span> Exception </span>&#123;</span><br><span class="line">    domParser.parse(<span class="hljs-keyword">new</span> InputSource(<span class="hljs-keyword">new</span> StringReader(content)));</span><br><span class="line">    <span class="hljs-keyword">return</span> domParser.getDocument();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">private</span> String <span class="hljs-title">readHtmlContent</span><span class="hljs-params">(String url)</span> <span class="hljs-keyword">throws</span> Exception </span>&#123;</span><br><span class="line">    InputStream in = HttpUtil.downFile(url);</span><br><span class="line">    StringBuilder out = <span class="hljs-keyword">new</span> StringBuilder();</span><br><span class="line">    <span class="hljs-keyword">byte</span>[] b = <span class="hljs-keyword">new</span> <span class="hljs-keyword">byte</span>[<span class="hljs-number">4096</span>];</span><br><span class="line">    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> n; (n = in.read(b)) != -<span class="hljs-number">1</span>; ) &#123;</span><br><span class="line">        out.append(<span class="hljs-keyword">new</span> String(b, <span class="hljs-number">0</span>, n));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="hljs-keyword">return</span> out.toString();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="hljs-meta">@Test</span></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">testRender</span><span class="hljs-params">()</span> </span>&#123;</span><br><span class="line">    <span class="hljs-keyword">try</span> &#123;</span><br><span class="line">        String url = <span class="hljs-string">"http://www.baidu.com"</span>;</span><br><span class="line">        Document doc = parseDocument(readHtmlContent(url));</span><br><span class="line"></span><br><span class="line">        <span class="hljs-keyword">int</span> width = <span class="hljs-number">800</span>;</span><br><span class="line">        <span class="hljs-keyword">int</span> height = <span class="hljs-number">1024</span>;</span><br><span class="line">        Graphics2DRenderer renderer = <span class="hljs-keyword">new</span> Graphics2DRenderer();</span><br><span class="line">        renderer.setDocument(doc, doc.getDocumentURI());</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">        BufferedImage bufferedImage = <span class="hljs-keyword">new</span> BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);</span><br><span class="line">        Graphics2D graphics2D = GraphicUtil.getG2d(bufferedImage);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">        <span class="hljs-comment">// do layout with temp buffer</span></span><br><span class="line">        renderer.layout(graphics2D, <span class="hljs-keyword">new</span> Dimension(width, height));</span><br><span class="line">        graphics2D.dispose();</span><br><span class="line"></span><br><span class="line">        Rectangle size = renderer.getMinimumSize();</span><br><span class="line">        <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> autoWidth = width;</span><br><span class="line">        <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> autoHeight = (<span class="hljs-keyword">int</span>) size.getHeight();</span><br><span class="line">        bufferedImage = <span class="hljs-keyword">new</span> BufferedImage(autoWidth, autoHeight, BufferedImage.TYPE_INT_RGB);</span><br><span class="line">        Dimension dimension = <span class="hljs-keyword">new</span> Dimension(autoWidth, autoHeight);</span><br><span class="line"></span><br><span class="line">        graphics2D = GraphicUtil.getG2d(bufferedImage);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">        renderer.layout(graphics2D, dimension);</span><br><span class="line">        renderer.render(graphics2D);</span><br><span class="line">        graphics2D.dispose();</span><br><span class="line">        System.out.println(<span class="hljs-string">"---------"</span>);</span><br><span class="line">    &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;</span><br><span class="line">        e.printStackTrace();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>结果输出图片为空白的页面，为啥？ 仔细去看百度的网页，发现没有dom结构，一堆的js和css代码，换个本地的html来试一下，输出效果还不错，我之前做了一个小工具，实现markdown转image，就是用的这个框架做中转，将markdown生成的html渲染为图片，当然复杂一点的css就不行了</p>
<p>相信看到这里，这个库的缺陷也好很明显了，不适合生产环境，自己玩玩还行</p>
<ul>
<li>过于古老，基本没人维护</li>
<li>对html的格式有要求</li>
<li>复杂的css没法玩</li>
<li>指定宽度也比较恶心</li>
</ul>
<hr>
<h4 id="c-借助转pdf的包"><a href="#c-借助转pdf的包" class="headerlink" title="c. 借助转pdf的包"></a>c. 借助转pdf的包</h4><p>java中，提供html转pdf的包还不少，借助这些工具，也是可以间接实现这个功能的，具体的就不贴了，可以用的不少，收钱的，免费的都有</p>
<p>推荐几个搞标记的</p>
<ul>
<li><a href="https://github.com/flyingsaucerproject/flyingsaucer" target="_blank" rel="noopener">flyingsaucer</a></li>
<li><a href="https://github.com/danfickle/openhtmltopdf" target="_blank" rel="noopener">openhtmltopdf</a></li>
<li><a href="https://github.com/itext" target="_blank" rel="noopener">itext</a></li>
</ul>
<hr>
<h4 id="d-小结"><a href="#d-小结" class="headerlink" title="d. 小结"></a>d. 小结</h4><p>基本上，没有找到合乎心意的转换包，其实有些包也不错，如果深入进去改一波，应该也能使用，然实际就是深入进去，基本上挖不动</p>
<hr>
<h3 id="1-imagemagic的合成"><a href="#1-imagemagic的合成" class="headerlink" title="1. imagemagic的合成"></a>1. imagemagic的合成</h3><p>大名鼎鼎的图片处理工具，c++的，可以提供图片的各种姿势的操作，当然也包括了图片合成，要玩这个，首先得搭建这个环境（这个成本比上面会大一点）</p>
<h4 id="a-环境准备"><a href="#a-环境准备" class="headerlink" title="a. 环境准备"></a>a. 环境准备</h4><p>简单搭建方式：</p>
<figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">yum install libjpeg-devel</span><br><span class="line">yum install libpng-devel</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"># 本地环境搭建</span><br><span class="line">sudo brew install jpeg</span><br><span class="line">sudo brew install libpng</span><br><span class="line">sudo brew install GraphicsMagick</span><br></pre></td></tr></table></figure>
<p>搭建完毕后，测试先是否可用</p>
<figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">## 搭建完毕，开始测试</span><br><span class="line">gm convert input.jpg -thumbnail &apos;100x100&apos; output_1.jpg</span><br><span class="line"></span><br><span class="line">gm convert -crop 640x960+0+0 test.jpg output.jpg</span><br></pre></td></tr></table></figure>
<p>如果上面的搞不定，也可以用下面的下载包的方式安装</p>
<figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">安装jpeg 包 `wget ftp://223.202.54.10/pub/web/php/libjpeg-6b.tar.gz`</span><br><span class="line">安装webp 包 `wget http://www.imagemagick.org/download/delegates/libwebp-0.5.1.tar.gz`</span><br><span class="line">安装png 包 `wget http://www.imagemagick.org/download/delegates/libpng-1.6.24.tar.gz`</span><br><span class="line">安装 graphicsmagick `wget http://nchc.dl.sourceforge.net/project/graphicsmagick/graphicsmagick/1.3.22/GraphicsMagick-1.3.22.tar.gz`</span><br><span class="line"></span><br><span class="line">## ----------</span><br><span class="line"></span><br><span class="line">make distclean ##  清楚上次make的东西</span><br><span class="line"></span><br><span class="line">imagemagick ：</span><br><span class="line"></span><br><span class="line">`wget http://www.imagemagick.org/download/ImageMagick.tar.gz`</span><br><span class="line"></span><br><span class="line">安装命令  `sudo ./configure; sudo make; sudo make install`</span><br><span class="line"></span><br><span class="line">裁图命令 `convert test.jpg -crop 640x960+0+0 output.jpg`</span><br></pre></td></tr></table></figure>
<p>linux 安装imagemagick 发现一直找不到 png的依赖，</p>
<p>linux 安装之后，可能有两个问题</p>
<ul>
<li><p>imagemagick 依然无法读取png图片</p>
<ul>
<li>查阅需要安装 <a href="http://pkgconfig.freedesktop.org/releases/pkg-config-0.28.tar.gz" target="_blank" rel="noopener">http://pkgconfig.freedesktop.org/releases/pkg-config-0.28.tar.gz</a></li>
</ul>
</li>
<li><p>执行 convert 提示linux shared libraries 不包含某个库 </p>
<ul>
<li>临时解决方案： export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH</li>
<li>一劳永逸的方案：<a href="https://my.oschina.net/guanyue/blog/220264" target="_blank" rel="noopener">https://my.oschina.net/guanyue/blog/220264</a><ul>
<li>vi /etc/ld.so.conf 在这个文件里加入：/usr/local/lib 来指明共享库的搜索位置 然后再执行/sbin/ldconf</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<h4 id="b-java调用"><a href="#b-java调用" class="headerlink" title="b. java调用"></a>b. java调用</h4><p>当然，我们是java的后端，现在就需要用java来调用imagemagic的执行了</p>
<p>依赖包</p>
<figure class="highlight xml hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.im4java<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>im4java<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.4.0<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>下面给一个图片裁剪的测试</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment"> * 裁剪图片</span></span><br><span class="line"><span class="hljs-comment"> *</span></span><br><span class="line"><span class="hljs-comment"> * <span class="hljs-doctag">@param</span> imagePath 源图片路径</span></span><br><span class="line"><span class="hljs-comment"> * <span class="hljs-doctag">@param</span> outPath   处理后图片路径</span></span><br><span class="line"><span class="hljs-comment"> * <span class="hljs-doctag">@param</span> x         起始X坐标</span></span><br><span class="line"><span class="hljs-comment"> * <span class="hljs-doctag">@param</span> y         起始Y坐标</span></span><br><span class="line"><span class="hljs-comment"> * <span class="hljs-doctag">@param</span> width     裁剪宽度</span></span><br><span class="line"><span class="hljs-comment"> * <span class="hljs-doctag">@param</span> height    裁剪高度</span></span><br><span class="line"><span class="hljs-comment"> * <span class="hljs-doctag">@return</span> 返回true说明裁剪成功, 否则失败</span></span><br><span class="line"><span class="hljs-comment"> */</span></span><br><span class="line"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">cut</span><span class="hljs-params">(String imagePath, String outPath, <span class="hljs-keyword">int</span> x, <span class="hljs-keyword">int</span> y,</span></span></span><br><span class="line"><span class="hljs-function"><span class="hljs-params">                          <span class="hljs-keyword">int</span> width, <span class="hljs-keyword">int</span> height)</span> </span>&#123;</span><br><span class="line">    <span class="hljs-keyword">boolean</span> flag;</span><br><span class="line">    <span class="hljs-keyword">try</span> &#123;</span><br><span class="line">        IMOperation op = <span class="hljs-keyword">new</span> IMOperation();</span><br><span class="line">        op.addImage(imagePath);</span><br><span class="line">        <span class="hljs-comment">/** width：裁剪的宽度 * height：裁剪的高度 * x：裁剪的横坐标 * y：裁剪纵坐标 */</span></span><br><span class="line">        op.crop(width, height, x, y);</span><br><span class="line">        op.addImage(outPath);</span><br><span class="line">        <span class="hljs-comment">// 传true到构造函数中,则表示使用GraphicMagic, 裁图时,图片大小会变</span></span><br><span class="line">        ConvertCmd convert = <span class="hljs-keyword">new</span> ConvertCmd();</span><br><span class="line">        convert.run(op);</span><br><span class="line">        flag = <span class="hljs-keyword">true</span>;</span><br><span class="line">    &#125; <span class="hljs-keyword">catch</span> (IOException e) &#123;</span><br><span class="line">        flag = <span class="hljs-keyword">false</span>;</span><br><span class="line">    &#125; <span class="hljs-keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">        flag = <span class="hljs-keyword">false</span>;</span><br><span class="line">    &#125; <span class="hljs-keyword">catch</span> (IM4JavaException e) &#123;</span><br><span class="line">        flag = <span class="hljs-keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="hljs-keyword">return</span> flag;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>具体使用姿势就不说了，这个框架本身是支持简单的图片合成的，几张图和一下，加上文字水印啥的，主要说一下有什么问题</p>
<ul>
<li>图片合成参数不是一般的复杂，想实现一个模板的合成，这个命令可以说很难完美的写出来</li>
<li>性能一般般</li>
</ul>
<p>总得来说，这个用来做图片的基本操作还很好，真心不太合适复杂点的图片合成，分分钟虐哭</p>
<h4 id="c-其他一些不得不说的故事"><a href="#c-其他一些不得不说的故事" class="headerlink" title="c. 其他一些不得不说的故事"></a>c. 其他一些不得不说的故事</h4><p>说到imagemagic，就不得不说graphicmagic，两者基本差不多，有说法是 graphicmagic的性能要高与imagemagic，那么我们为什么选择 imagemagic</p>
<ul>
<li>graphicmagic 处理jpg图片，会有精度丢失的问题（不知道是不是我的使用姿势不对，同样的case，imagemagic不会）</li>
<li>公司的基线是支持imagemagic的</li>
</ul>
<p>很久以前写了一篇博文，就是如何利用 imagegraphic 搭建一个图片处理服务器的</p>
<ul>
<li><a href="https://my.oschina.net/u/566591/blog/778851" target="_blank" rel="noopener">im4java + imagemagic 搭建一个图片处理服务</a></li>
</ul>
<hr>
<h3 id="2-awt的绘制"><a href="#2-awt的绘制" class="headerlink" title="2. awt的绘制"></a>2. awt的绘制</h3><p>利用java的awt包，也是可以实现绘图的，而且功能也比较强大，完全可以实现各种姿势的绘图场景, 一个case如 :</p>
<p><img src="http://s3.mogucdn.com/mlcdn/c45406/171203_36j204d8e1deild5li4c116b9c137_640x340.jpg" alt="case"></p>
<p>上面这个图的合成，就是基于awt做到的，这一张图，我们需要做些什么？</p>
<ul>
<li>图片的绘制</li>
<li>圆角图片</li>
<li>文字输出</li>
<li>文字对其方式</li>
<li>直线</li>
<li>矩形</li>
<li>纯色背景</li>
</ul>
<p>一般来将，上面几种场景的支持，可以满足绝大多数的合图要求，接下来看一下是如何支持上面的几种case的</p>
<h4 id="o-接口定义"><a href="#o-接口定义" class="headerlink" title="o. 接口定义"></a>o. 接口定义</h4><p>定义一个基本的绘图单元接口</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">IDrawBO</span> </span>&#123;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="a-图片-：-ImgBO"><a href="#a-图片-：-ImgBO" class="headerlink" title="a. 图片 ： ImgBO"></a>a. 图片 ： ImgBO</h4><p>图片的定义比较简单，一般只需要知道坐标，和宽高就ok了，所以我们的定义如下</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-meta">@Data</span></span><br><span class="line"><span class="hljs-meta">@NoArgsConstructor</span></span><br><span class="line"><span class="hljs-meta">@AllArgsConstructor</span></span><br><span class="line"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ImgBO</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">IDrawBO</span> </span>&#123;</span><br><span class="line">    <span class="hljs-keyword">private</span> BufferedImage image;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> x;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> y;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> w;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> h;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="b-文字：FontBO"><a href="#b-文字：FontBO" class="headerlink" title="b. 文字：FontBO"></a>b. 文字：FontBO</h4><p>文字相比较图片就有些额外的区别，有字体，样式、颜色，坐标，删除线</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-meta">@Data</span></span><br><span class="line"><span class="hljs-meta">@NoArgsConstructor</span></span><br><span class="line"><span class="hljs-meta">@AllArgsConstructor</span></span><br><span class="line"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FontBO</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">IDrawBO</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> String msgs;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> Font font;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> Color color;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> x;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> y;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">boolean</span> deleted = <span class="hljs-keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="c-直线-LineBO"><a href="#c-直线-LineBO" class="headerlink" title="c. 直线: LineBO"></a>c. 直线: LineBO</h4><p>直线，除了我们常规的起点坐标，末尾坐标之外，颜色的设置，虚线样式也是常见的属性</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-meta">@Data</span></span><br><span class="line"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LineBO</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">IDrawBO</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> Stroke DEFAULT_STROKE = <span class="hljs-keyword">new</span> BasicStroke(<span class="hljs-number">2</span>,</span><br><span class="line">            BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND,</span><br><span class="line">            <span class="hljs-number">3.5f</span>,</span><br><span class="line">            <span class="hljs-keyword">new</span> <span class="hljs-keyword">float</span>[]&#123;<span class="hljs-number">12</span>, <span class="hljs-number">6</span>, <span class="hljs-number">6</span>, <span class="hljs-number">6</span>&#125;,</span><br><span class="line">            <span class="hljs-number">0f</span>);</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> Color color;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> x1;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> y1;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> x2;</span><br><span class="line">    </span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> y2;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">     * 是否是虚线</span></span><br><span class="line"><span class="hljs-comment">     */</span></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">boolean</span> dashed;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="d-矩形：-RoundRectBO"><a href="#d-矩形：-RoundRectBO" class="headerlink" title="d. 矩形： RoundRectBO"></a>d. 矩形： RoundRectBO</h4><p>和直线的属性差不多, 但是会多一些有意思的东西，如是否为圆角矩形</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RoundRectBO</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">IDrawBO</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> Stroke DEFAULT_DASH = <span class="hljs-keyword">new</span> BasicStroke(<span class="hljs-number">1</span>,</span><br><span class="line">            BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND,</span><br><span class="line">            <span class="hljs-number">3.5f</span>,</span><br><span class="line">            <span class="hljs-keyword">new</span> <span class="hljs-keyword">float</span>[]&#123;<span class="hljs-number">4</span>, <span class="hljs-number">2</span>,&#125;,</span><br><span class="line">            <span class="hljs-number">0f</span>);</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> x;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> y;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> w;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> h;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> Color color;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">     * 是否为虚线</span></span><br><span class="line"><span class="hljs-comment">     */</span></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">boolean</span> dashed;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment">     * 圆角弧度</span></span><br><span class="line"><span class="hljs-comment">     */</span></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> radius;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="e-纯色：-ColorBgBO"><a href="#e-纯色：-ColorBgBO" class="headerlink" title="e. 纯色： ColorBgBO"></a>e. 纯色： ColorBgBO</h4><p>纯色背景，相比较其他的会多一个透明度的属性，主要是因为很多场景下，会做一层纯色的浮层</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-meta">@Data</span></span><br><span class="line"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ColorBgBO</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">IDrawBO</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> Color color;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> w;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> h;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> x;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> y;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> radius;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">private</span> <span class="hljs-keyword">boolean</span> transparence;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<hr>
<p>上面定义了这些BO对象，仅仅是定义又什么用？接下来就需要实现对BO对象的绘制，也是核心的逻辑层了</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">/**</span></span><br><span class="line"><span class="hljs-comment"> * Created by yihui on 2017/9/21.</span></span><br><span class="line"><span class="hljs-comment"> */</span></span><br><span class="line"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">IShareModule</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">draw</span><span class="hljs-params">(Graphics2D g2d)</span></span>;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="hljs-function"><span class="hljs-keyword">default</span> <span class="hljs-keyword">void</span> <span class="hljs-title">drawFont</span><span class="hljs-params">(Graphics2D g2d, FontBO fontBo)</span> </span>&#123;</span><br><span class="line">        <span class="hljs-keyword">if</span> (fontBo != <span class="hljs-keyword">null</span>) &#123;</span><br><span class="line">            g2d.setFont(fontBo.getFont());</span><br><span class="line">            g2d.setColor(fontBo.getColor());</span><br><span class="line">            g2d.drawString(fontBo.getMsgs(), fontBo.getX(), fontBo.getY());</span><br><span class="line"></span><br><span class="line">            <span class="hljs-keyword">if</span> (fontBo.isDeleted()) &#123; <span class="hljs-comment">// 删除时，需要在文字上绘制一条删除线</span></span><br><span class="line">                FontMetrics fontMetrics = FontUtil.getFontMetric(fontBo.getFont());</span><br><span class="line">                <span class="hljs-keyword">int</span> y = fontBo.getY() - (fontBo.getFont().getSize() &gt;&gt; <span class="hljs-number">1</span>) + fontMetrics.getDescent();</span><br><span class="line">                <span class="hljs-keyword">int</span> w = fontMetrics.stringWidth(fontBo.getMsgs());</span><br><span class="line"></span><br><span class="line">                g2d.drawLine(fontBo.getX(), y, fontBo.getX() + w, y);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="hljs-function"><span class="hljs-keyword">default</span> <span class="hljs-keyword">void</span> <span class="hljs-title">drawImage</span><span class="hljs-params">(Graphics2D g2d, ImgBO imgBo)</span> </span>&#123;</span><br><span class="line">        <span class="hljs-keyword">if</span> (imgBo != <span class="hljs-keyword">null</span>) &#123;</span><br><span class="line">            g2d.drawImage(imgBo.getImage(), imgBo.getX(), imgBo.getY(), imgBo.getW(), imgBo.getH(), <span class="hljs-keyword">null</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="hljs-function"><span class="hljs-keyword">default</span> <span class="hljs-keyword">void</span> <span class="hljs-title">drawLine</span><span class="hljs-params">(Graphics2D g2d, LineBO lineBO)</span> </span>&#123;</span><br><span class="line">        <span class="hljs-keyword">if</span>(lineBo == <span class="hljs-keyword">null</span>) <span class="hljs-keyword">return</span>;</span><br><span class="line">        g2d.setColor(lineBO.getColor());</span><br><span class="line">        <span class="hljs-keyword">if</span> (lineBO.isDashed()) &#123;</span><br><span class="line">            Stroke stroke = g2d.getStroke();</span><br><span class="line">            g2d.setStroke(LineBO.DEFAULT_STROKE);</span><br><span class="line">            g2d.drawLine(lineBO.getX(), lineBO.getY(), lineBO.getX() + lineBO.getW(), lineBO.getY());</span><br><span class="line">            g2d.setStroke(stroke);</span><br><span class="line">        &#125; <span class="hljs-keyword">else</span> &#123;</span><br><span class="line">            g2d.drawLine(lineBO.getX(), lineBO.getY(), lineBO.getX() + lineBO.getW(), lineBO.getY());</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="hljs-function"><span class="hljs-keyword">default</span> <span class="hljs-keyword">void</span> <span class="hljs-title">drawRoundRect</span><span class="hljs-params">(Graphics2D g2d, RoundRectBO roundRectBO)</span> </span>&#123;</span><br><span class="line">        <span class="hljs-keyword">if</span>(roundRectBO == <span class="hljs-keyword">null</span>) <span class="hljs-keyword">return</span>;</span><br><span class="line">        g2d.setColor(roundRectBO.getColor());</span><br><span class="line">        <span class="hljs-keyword">if</span> (!roundRectBO.isDashed()) &#123;</span><br><span class="line">            g2d.drawRoundRect(roundRectBO.getX(), roundRectBO.getY(),</span><br><span class="line">                    roundRectBO.getW(),</span><br><span class="line">                    roundRectBO.getH(),</span><br><span class="line">                    roundRectBO.getRadius(),</span><br><span class="line">                    roundRectBO.getRadius());</span><br><span class="line">        &#125; <span class="hljs-keyword">else</span> &#123;</span><br><span class="line">            Stroke stroke = g2d.getStroke();</span><br><span class="line"></span><br><span class="line">            g2d.setStroke(RoundRectBO.DEFAULT_DASH);</span><br><span class="line">            g2d.drawRoundRect(roundRectBO.getX(), roundRectBO.getY(),</span><br><span class="line">                    roundRectBO.getW(),</span><br><span class="line">                    roundRectBO.getH(),</span><br><span class="line">                    roundRectBO.getRadius(),</span><br><span class="line">                    roundRectBO.getRadius());</span><br><span class="line">            g2d.setStroke(stroke);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">        <span class="hljs-keyword">if</span> (roundRectBO.getSpaceW() &gt; <span class="hljs-number">0</span>) &#123; <span class="hljs-comment">// 上边距空白的宽度</span></span><br><span class="line">            <span class="hljs-keyword">int</span> x = roundRectBO.getX() + (roundRectBO.getW() - roundRectBO.getSpaceW() &gt;&gt; <span class="hljs-number">1</span>);</span><br><span class="line">            <span class="hljs-keyword">int</span> y = roundRectBO.getY() - <span class="hljs-number">2</span>;</span><br><span class="line">            <span class="hljs-keyword">int</span> w = roundRectBO.getSpaceW();</span><br><span class="line">            <span class="hljs-keyword">int</span> h = <span class="hljs-number">4</span>;</span><br><span class="line">            g2d.setColor(roundRectBO.getSpaceColor());</span><br><span class="line">            g2d.fillRect(x, y, w, h);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line">    <span class="hljs-function"><span class="hljs-keyword">default</span> <span class="hljs-keyword">void</span> <span class="hljs-title">drawColorBG</span><span class="hljs-params">(Graphics2D g2d, ColorBgBO color)</span> </span>&#123;</span><br><span class="line">        <span class="hljs-keyword">if</span>(color == <span class="hljs-keyword">null</span>) <span class="hljs-keyword">return</span>;</span><br><span class="line">        g2d.setColor(color.getColor());</span><br><span class="line"></span><br><span class="line">        Composite composite = <span class="hljs-keyword">null</span>;</span><br><span class="line">        <span class="hljs-keyword">if</span> (color.isTransparence()) &#123;</span><br><span class="line">            composite = g2d.getComposite();</span><br><span class="line">            g2d.setComposite(AlphaComposite.Src);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="hljs-keyword">if</span> (color.getRadius() == <span class="hljs-number">0</span>) &#123;</span><br><span class="line">            g2d.fillRect(color.getX(), color.getY(), color.getW(), color.getH());</span><br><span class="line">        &#125; <span class="hljs-keyword">else</span> &#123;</span><br><span class="line">            g2d.fill(<span class="hljs-keyword">new</span> RoundRectangle2D.Float(color.getX(), color.getY(), color.getW(), color.getH(), color.getRadius(), color.getRadius()));</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="hljs-keyword">if</span> (color.isTransparence()) &#123;</span><br><span class="line">            g2d.setComposite(composite);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>上面配合起来使用，就可以实现基本的模板图片的合成需求了，当然我们提供的服务比上面列出的要丰富一些，我们还支持</p>
<ul>
<li>图片的处理：圆角，裁剪贴图</li>
<li>文字对齐：三种对齐方式，自动换行</li>
</ul>
<hr>
<h4 id="小结-amp-问题"><a href="#小结-amp-问题" class="headerlink" title="小结&amp;问题"></a>小结&amp;问题</h4><p>上面虽然说可以支持合图的需求，但有个最大的问题，就是对后端的工作太多，每个模板，都需要后端来配合，进行参数指定，联调，极其繁琐和费时费力，分分钟搞死人</p>
<p>对这种方式，想的一个方法是，采用搭积木的方式支持，事先定义一系列的基本绘图组建，然后前端自己填入参数来组装</p>
<p>当然没有做，原因也很简单，接口太复杂，对前端不友好，没人愿意这么用，换成我也是不想这么干的</p>
<hr>
<h3 id="3-html-转-图片"><a href="#3-html-转-图片" class="headerlink" title="3. html 转 图片"></a>3. html 转 图片</h3><p>接着又来的是一个猥琐的方案，html转图，到github上一搜，发现还是js靠谱，比较多，一种常见的思路是：</p>
<p><strong>采用无界面浏览器加载html页面，然后截图</strong></p>
<p>在无界面浏览器中，非常有名的是 phantomjs，以及后起之秀chrome，这里主要说一下phantomjs的接入方式，简单提起chrmoe的无界面使用方式</p>
<h4 id="a-环境准备-1"><a href="#a-环境准备-1" class="headerlink" title="a. 环境准备"></a>a. 环境准备</h4><p>phantomjs 安装</p>
<figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"># 1. 下载</span><br><span class="line"></span><br><span class="line">## mac 系统</span><br><span class="line">wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-macosx.zip</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## linux 系统</span><br><span class="line">wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2</span><br><span class="line"></span><br><span class="line">## windows 系统</span><br><span class="line">## 就不要玩了，没啥意思</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"># 2. 解压</span><br><span class="line"></span><br><span class="line">sudo su </span><br><span class="line">tar -jxvf phantomjs-2.1.1-linux-x86_64.tar.bz2</span><br><span class="line"></span><br><span class="line"># 如果解压报错，则安装下面的</span><br><span class="line"># yum -y install bzip2</span><br><span class="line"></span><br><span class="line"># 3. 安装</span><br><span class="line"></span><br><span class="line">## 简单点，移动到bin目录下</span><br><span class="line"></span><br><span class="line">cp phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin</span><br><span class="line"></span><br><span class="line"># 4. 验证是否ok</span><br><span class="line">phantomjs --version</span><br><span class="line"></span><br><span class="line"># 输出版本号，则表示ok</span><br></pre></td></tr></table></figure>
<p>pom依赖</p>
<figure class="highlight xml hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">&lt;!--phantomjs --&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.seleniumhq.selenium<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>selenium-java<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.53.1<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.github.detro<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>ghostdriver<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.1.0<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">repositories</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">repository</span>&gt;</span></span><br><span class="line">        <span class="hljs-tag">&lt;<span class="hljs-name">id</span>&gt;</span>jitpack.io<span class="hljs-tag">&lt;/<span class="hljs-name">id</span>&gt;</span></span><br><span class="line">        <span class="hljs-tag">&lt;<span class="hljs-name">url</span>&gt;</span>https://jitpack.io<span class="hljs-tag">&lt;/<span class="hljs-name">url</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;/<span class="hljs-name">repository</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">repositories</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h4 id="b-实测"><a href="#b-实测" class="headerlink" title="b. 实测"></a>b. 实测</h4><p>思路比较清晰，在服务器上搭建一个phantomjs服务，然后java来调用，主要借助的是selenium和ghostdriver两个开源包，额外提一句，selenium在自动化测试和爬虫使用中非常有名，有兴趣的可以自己搜索相关资料，非常有意思的一个东西</p>
<p><strong>图片渲染的主要业务逻辑：</strong></p>
<figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">public class Html2ImageByJsWrapper &#123;</span><br><span class="line"></span><br><span class="line">    private static PhantomJSDriver webDriver = getPhantomJs();</span><br><span class="line"></span><br><span class="line">    private static PhantomJSDriver getPhantomJs() &#123;</span><br><span class="line">        //设置必要参数</span><br><span class="line">        DesiredCapabilities dcaps = new DesiredCapabilities();</span><br><span class="line">        //ssl证书支持</span><br><span class="line">        dcaps.setCapability(&quot;acceptSslCerts&quot;, true);</span><br><span class="line">        //截屏支持</span><br><span class="line">        dcaps.setCapability(&quot;takesScreenshot&quot;, true);</span><br><span class="line">        //css搜索支持</span><br><span class="line">        dcaps.setCapability(&quot;cssSelectorsEnabled&quot;, true);</span><br><span class="line">        //js支持</span><br><span class="line">        dcaps.setJavascriptEnabled(true);</span><br><span class="line">        //驱动支持（第二参数表明的是你的phantomjs引擎所在的路径，which/whereis phantomjs可以查看）</span><br><span class="line">        // fixme 这里写了执行， 可以考虑判断系统是否有安装，并获取对应的路径 or 开放出来指定路径</span><br><span class="line">        dcaps.setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, &quot;/usr/local/bin/phantomjs&quot;);</span><br><span class="line">        //创建无界面浏览器对象</span><br><span class="line">        return new PhantomJSDriver(dcaps);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public static BufferedImage renderHtml2Image(String url) throws IOException &#123;</span><br><span class="line">        webDriver.get(url);</span><br><span class="line">        File file = webDriver.getScreenshotAs(OutputType.FILE);</span><br><span class="line">        return ImageIO.read(file);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>那么测试case就很好写了</p>
<figure class="highlight plain hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">@Test</span><br><span class="line">public void testRender() throws IOException &#123;</span><br><span class="line">    String url = &quot;https://www.baidu.com&quot;;</span><br><span class="line">    BufferedImage img = Html2ImageByJsWrapper.renderHtml2Image(url);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>输出图片</p>
<p><img src="http://s2.mogucdn.com/mlcdn/c45406/171217_1g98bj21aldjl0655h0adh8dh216a_810x600.jpg" alt="IMAGE"></p>
<p>看到这个结果之后，是否会觉得已经完美了？</p>
<p>然而并不是，测试一些需要异步请求的接口，比较渣，性能差，返回的样式会错乱</p>
<h4 id="c-分析小结"><a href="#c-分析小结" class="headerlink" title="c. 分析小结"></a>c. 分析小结</h4><p>这个方案从实现来讲，是没有什么问题的，从支持情况来说，问题其实也不太大，那为什么不用这个方案呢？</p>
<p>这个方案的支持，原本我的希望是前端传给我们需要渲染的html</p>
<ul>
<li>是直出好的页面</li>
<li>所有的dom结构已经很清晰了，</li>
<li>尽量不要有什么js，</li>
<li>不要有异步请求，</li>
<li>不要又复杂的css依赖，</li>
<li>没有大量的图片</li>
</ul>
<p>然而事与愿违，至于为什么不实现这样的html，我也不太懂前端的技术难点在哪，不好多评，那么也就只好转方案了 </p>
<p>还有一点，对这个方案我不太满意的就是性能太渣，而且我也不知道可以怎么去优化，简单来讲，就是这个js渲染，完全不在我的把控之内，有什么问题、如何去优化、如何防止ssrf攻击，我都没有好的解决办法，所以我本人也是不喜欢这个方案的</p>
<h4 id="d-chrome-方式"><a href="#d-chrome-方式" class="headerlink" title="d. chrome 方式"></a>d. chrome 方式</h4><p>chrome浏览器，大家都知道，chrome还有一种无界面启动方式，可能知道的比较少了</p>
<p>只要你本机安装了chrome浏览器，打开控制台就可以愉快的玩耍了，html输出图片的指令为</p>
<figure class="highlight sh hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">## 输出pdf</span></span><br><span class="line">/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --headless --<span class="hljs-built_in">print</span>-to-pdf http://www.baidu.com</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">## 输出图片</span></span><br><span class="line">/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --headless --screenshot  http://www.baidu.com</span><br></pre></td></tr></table></figure>
<p>输出截图</p>
<p><img src="http://s2.mogucdn.com/mlcdn/c45406/171217_3j6jcb9h24k4afkhih2gj5771l926_1600x1200.png" alt="screenshot.png"></p>
<p><strong>说明</strong></p>
<p>chrome headless有很多指令，可设置窗口的大小解决上面的边框问题，有兴趣的可以百度</p>
<hr>
<h3 id="4-svg-转-图片"><a href="#4-svg-转-图片" class="headerlink" title="4. svg 转 图片"></a>4. svg 转 图片</h3><p>然后万能的前端同学又提出了svg渲染图片，在提这个之前，完全没接触过svg，也不知道svg是个什么鬼，更不知道svg能不能渲染出图片（最重要的是java有没有现成可用的库）</p>
<p>查了一番，不错，发现apace有个batik，就是干这个事情的</p>
<pre><code>插播一句，感觉无论多偏的东西，apache或者是google都至少有那么一个可以支持的开源项目，虽然有不少都已经不怎么维护了
</code></pre><h4 id="a-依赖整理"><a href="#a-依赖整理" class="headerlink" title="a. 依赖整理"></a>a. 依赖整理</h4><p>依赖包有那么点多</p>
<figure class="highlight xml hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">&lt;!--batik svg to image--&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.xmlgraphics<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>batik-svggen<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.8<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.xmlgraphics<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>batik-bridge<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.8<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">exclusions</span>&gt;</span></span><br><span class="line">        <span class="hljs-tag">&lt;<span class="hljs-name">exclusion</span>&gt;</span></span><br><span class="line">            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>xalan<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>xalan<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="hljs-tag">&lt;/<span class="hljs-name">exclusion</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;/<span class="hljs-name">exclusions</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.xmlgraphics<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>batik-dom<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.8<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">exclusions</span>&gt;</span></span><br><span class="line">        <span class="hljs-tag">&lt;<span class="hljs-name">exclusion</span>&gt;</span></span><br><span class="line">            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>xalan<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>xalan<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="hljs-tag">&lt;/<span class="hljs-name">exclusion</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;/<span class="hljs-name">exclusions</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.xmlgraphics<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>batik-parser<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.8<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.xmlgraphics<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>batik-svg-dom<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.8<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.xmlgraphics<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>batik-transcoder<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.8<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.xmlgraphics<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>batik-util<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.8<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.xmlgraphics<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>batik-xml<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.8<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line"><span class="hljs-comment">&lt;!-- https://mvnrepository.com/artifact/org.apache.xmlgraphics/xmlgraphics-commons --&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.xmlgraphics<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>xmlgraphics-commons<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.1<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line"><span class="hljs-comment">&lt;!-- https://mvnrepository.com/artifact/org.apache.xmlgraphics/batik-codec --&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.xmlgraphics<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>batik-codec<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.8<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span> <span class="hljs-comment">&lt;!-- 此处不能使用2.9.1版本，使用2.9.1生成png会失败 --&gt;</span></span><br><span class="line"><span class="hljs-comment">&lt;!--&lt;dependency&gt;--&gt;</span></span><br><span class="line">    <span class="hljs-comment">&lt;!--&lt;groupId&gt;xerces&lt;/groupId&gt;--&gt;</span></span><br><span class="line">    <span class="hljs-comment">&lt;!--&lt;artifactId&gt;xercesImpl&lt;/artifactId&gt;--&gt;</span></span><br><span class="line">    <span class="hljs-comment">&lt;!--&lt;version&gt;2.5.0&lt;/version&gt;--&gt;</span></span><br><span class="line"><span class="hljs-comment">&lt;!--&lt;/dependency&gt;--&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>xml-apis<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>xmlParserAPIs<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.0.2<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.axsl.org.w3c.dom.svg<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>svg-dom-java<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.1<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>xml-apis<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>xml-apis<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.0.0<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.w3c.css<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>sac<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.3<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span></span><br><span class="line"><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h4 id="b-实测-1"><a href="#b-实测-1" class="headerlink" title="b. 实测"></a>b. 实测</h4><p>一个简单的接口支持</p>
<figure class="highlight java hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">convertToPngByFile</span><span class="hljs-params">(String path, OutputStream outputStream, Map&lt;String, String&gt; parmMap)</span></span></span><br><span class="line"><span class="hljs-function">			<span class="hljs-keyword">throws</span> TranscoderException, IOException </span>&#123;</span><br><span class="line">	<span class="hljs-keyword">try</span> &#123;</span><br><span class="line">	  <span class="hljs-comment">// 1. 加载document</span></span><br><span class="line">		File file = <span class="hljs-keyword">new</span> File(path);</span><br><span class="line">		String parser = XMLResourceDescriptor.getXMLParserClassName();</span><br><span class="line">		SAXSVGDocumentFactory f = <span class="hljs-keyword">new</span> SAXSVGDocumentFactory(parser);</span><br><span class="line">		Document doc = f.createDocument(file.toURI().toString());</span><br><span class="line"></span><br><span class="line">		</span><br><span class="line">		<span class="hljs-comment">// 2. 遍历参数，填充渲染的svg节点</span></span><br><span class="line">		Set&lt;String&gt; keySet = parmMap.keySet();</span><br><span class="line">		<span class="hljs-keyword">for</span> (Map.Entry&lt;String, String&gt; entry : parmMap.entrySet()) &#123;</span><br><span class="line">			doc.getElementById(entry.getKey()).setTextContent(entry.getValue());</span><br><span class="line">		&#125;</span><br><span class="line">		</span><br><span class="line">		<span class="hljs-comment">// 3. 输出图片</span></span><br><span class="line">		PNGTranscoder t = <span class="hljs-keyword">new</span> PNGTranscoder();</span><br><span class="line">		TranscoderInput input = <span class="hljs-keyword">new</span> TranscoderInput(doc);</span><br><span class="line">		TranscoderOutput output = <span class="hljs-keyword">new</span> TranscoderOutput(outputStream);</span><br><span class="line">		t.transcode(input, output);</span><br><span class="line">		outputStream.flush();</span><br><span class="line">	&#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;</span><br><span class="line">		e.printStackTrace();</span><br><span class="line">	&#125; <span class="hljs-keyword">finally</span> &#123;</span><br><span class="line">		<span class="hljs-keyword">if</span> (outputStream != <span class="hljs-keyword">null</span>) &#123;</span><br><span class="line">			<span class="hljs-keyword">try</span> &#123;</span><br><span class="line">				outputStream.close();</span><br><span class="line">			&#125; <span class="hljs-keyword">catch</span> (IOException e) &#123;</span><br><span class="line">				e.printStackTrace();</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>上面主要是为了演示下使用姿势，实际的项目中肯定不会这么简陋，官方使用链接: <a href="https://xmlgraphics.apache.org/batik/using/transcoder.html" target="_blank" rel="noopener">https://xmlgraphics.apache.org/batik/using/transcoder.html</a></p>
<p>分析下主要流程</p>
<ul>
<li>解析svg文件，加载Document对象</li>
<li>根据传入的参数，填充Document中的节点</li>
<li>渲染输出图片</li>
</ul>
<p>测试演示就不来了，最终方案就是这个，成品也没啥好说的</p>
<h4 id="c-问题"><a href="#c-问题" class="headerlink" title="c. 问题"></a>c. 问题</h4><ol>
<li><p>文本的边框支持问题: 即 outline属性</p>
<p> 测试了好久，发现不支持这个属性</p>
</li>
<li><p>图片内容替换与文本内容替换是不一样的，需要区分对待</p>
</li>
<li><p>多个标签填充同样的内容时</p>
<p> 从接口上来看，支持一个根据Name来获取节点功能，但是实际测试，发现标签name属性，并没有什么鸟用；不知道是使用姿势问题还是别的</p>
<p> 然后翻看源码，发现当多个标签的id相同时，在Document的底层存储单元中，elementById 这个Map结构中，value会是一个数组</p>
<p> 然后自然而然的想法就是，直接遍历这个数组，依次填充内容就好；结果发现压根就没有暴露这个接口，而这个属性是protectd，也无法直接访问</p>
<p> 然后采用反射获取这个属性值，来绕过限制</p>
</li>
<li><p>模板加载缓存</p>
<p> 实际场景中，模板往往是固定的，每次都进行渲染是非常消耗性能的，因此想的是能不能缓存住这个Document，再使用的时候，直接深拷贝一个对象出来，这样就避免了重复加载的开销</p>
<p> 直接使用 <code>AbstractDocumen#deepClone(true)</code> 方法</p>
</li>
</ol>
<p>然后，出现了一个鬼畜的并发问题，这个单独领出来细说，此处不展开</p>
<hr>
<h2 id="III-最后收尾"><a href="#III-最后收尾" class="headerlink" title="III. 最后收尾"></a>III. 最后收尾</h2><p>鉴于篇幅太长，有一些有意思的东西没有深入展开，特别是svg方案的支持中，遇到了一些比较有趣的问题，也涉及到三个好玩的知识点： 深拷贝+反射+并发，后面准备等这一块完结之后，好好的沉淀下，分析下这个case</p>
<h3 id="1-吐槽"><a href="#1-吐槽" class="headerlink" title="1. 吐槽"></a>1. 吐槽</h3><p>后端支持已经很勉强了，请大家都友好点，比如下面几个我实在支持不了</p>
<ul>
<li>自定义设置字体（jdk字体，没新加一个都需要pe安装到jre的字体库）</li>
<li>图片的左上角圆角（暂时没想到好的解决方法）</li>
<li>渐变色（这个有点难）</li>
</ul>
<p>这个需求，做得比较恶心，支持得也比较蛋疼，实现得比较猥琐，调bug修问题也比较闹心，总得来说，是一个开始前很有趣，做时让人吐血又很不爽，做完之后又特么的很有收获的需求</p>
<p>发现特别能有收获的事情，往往不是哪种做的特别爽的需求（爽，是因为这些东西你都完全能hold住，没什么难度了），相反是那些让你很闹心，完全不想继续下去的需求（因为你不了解，但是又不得不支持，还会遇到一堆鬼畜的bug，做完简直是吐血三升）</p>
<h3 id="2-小结"><a href="#2-小结" class="headerlink" title="2. 小结"></a>2. 小结</h3><p>图片合成的方式，我想应该不仅限于上面几种，由于限制于见识，终究是没有一个让人特别满意的方案，简单小结下上面的几种case</p>
<ul>
<li>java的开源包<ul>
<li>html2image, xhtmlrender, pdfTech</li>
<li>一般来说，不怎么好用，大多不维护状态，对CSS的支持友好度待检验</li>
</ul>
</li>
<li>imagemagic<ul>
<li>适用于图片的基本处理，合图太复杂</li>
</ul>
</li>
<li>awt绘图<ul>
<li>属于基本的接口了，啥都可以干，只要你可以弄出来</li>
<li>但是工作量太大</li>
</ul>
</li>
<li>js实现html渲染<ul>
<li>phantmjs，效果不错，性能略渣，异步请求不友好，且完全不可控</li>
<li>chrome 性能由于上面的</li>
</ul>
</li>
<li>svg渲染<ul>
<li>batik</li>
<li>并不能非常完美的支持svg的渲染，有较多的限制要求，各种属性的必填，某些style的无法支持等</li>
<li>基本场景的支持，ok，优化后，性能高于html渲染，且可控</li>
</ul>
</li>
</ul>
<h2 id="III-其他"><a href="#III-其他" class="headerlink" title="III. 其他"></a>III. 其他</h2><h3 id="体验网址"><a href="#体验网址" class="headerlink" title="体验网址"></a>体验网址</h3><p>基于react写了个前端，可以来体验渲染</p>
<ul>
<li><a href="http://liuyueyi.gitee.io/zweb/#/tool/html2img" target="_blank" rel="noopener">phantomJs渲染</a></li>
<li><a href="http://liuyueyi.gitee.io/zweb/#/tool/svg" target="_blank" rel="noopener">svg渲染</a></li>
</ul>
<h3 id="个人博客：-一灰灰Blog"><a href="#个人博客：-一灰灰Blog" class="headerlink" title="个人博客： 一灰灰Blog"></a>个人博客： <a href="https://liuyueyi.github.io/hexblog" target="_blank" rel="noopener">一灰灰Blog</a></h3><p>基于hexo + github pages搭建的个人博客，记录所有学习和工作中的博文，欢迎大家前去逛逛</p>
<h3 id="声明"><a href="#声明" class="headerlink" title="声明"></a>声明</h3><p>尽信书则不如，已上内容，纯属一家之言，因本人能力一般，见识有限，如发现bug或者有更好的建议，随时欢迎批评指正</p>
<ul>
<li>微博地址: <a href="https://weibo.com/p/1005052169825577/home" target="_blank" rel="noopener">小灰灰Blog</a></li>
<li>QQ： 一灰灰/3302797840</li>
</ul>
<h3 id="扫描关注"><a href="#扫描关注" class="headerlink" title="扫描关注"></a>扫描关注</h3><p><img src="https://raw.githubusercontent.com/liuyueyi/Source/master/img/info/blogInfoV2.png" alt="QrCode"></p>


            
        </div>
        
        <div class="level is-size-7 is-uppercase">
            <div class="level-start">
                <div class="level-item">
                    <span class="is-size-6 has-text-grey has-mr-7">#</span>
                    <a class="has-link-grey -link" href="/hexblog/tags/手记/">手记</a>
                </div>
            </div>
        </div>
        
        
        
        <div class="bdsharebuttonbox">
    <a href="#" class="bds_more" data-cmd="more"></a>
    <a href="#" class="bds_qzone" data-cmd="qzone" title="分享到QQ空间"></a>
    <a href="#" class="bds_tsina" data-cmd="tsina" title="分享到新浪微博"></a>
    <a href="#" class="bds_tqq" data-cmd="tqq" title="分享到腾讯微博"></a>
    <a href="#" class="bds_renren" data-cmd="renren" title="分享到人人网"></a>
    <a href="#" class="bds_weixin" data-cmd="weixin" title="分享到微信"></a>
</div>
<script>window._bd_share_config = { "common": { "bdSnsKey": {}, "bdText": "", "bdMini": "2", "bdPic": "", "bdStyle": "0", "bdSize": "16" }, "share": {} }; with (document) 0[(getElementsByTagName('head')[0] || body).appendChild(createElement('script')).src = 'http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion=' + ~(-new Date() / 36e5)];</script>
        
    </div>
</div>



<div class="card">
    <div class="card-content">
        <h3 class="menu-label has-text-centered">喜欢这篇文章？打赏一下作者吧</h3>
        <div class="buttons is-centered">
            
                
<a class="button is-info donate">
    <span class="icon is-small">
        <i class="fab fa-alipay"></i>
    </span>
    <span>支付宝</span>
    <div class="qrcode"><img src="https://s3.mogucdn.com/mlcdn/c45406/180104_0e6afl33b23lacj6ji2d7d060aiak_798x800.png" alt="支付宝"></div>
</a>

                
                
<a class="button is-success donate">
    <span class="icon is-small">
        <i class="fab fa-weixin"></i>
    </span>
    <span>微信</span>
    <div class="qrcode"><img src="https://s11.mogucdn.com/mlcdn/c45406/180527_09cafb94a5g3lbd5ik6ke0hf649ff_800x798.jpg" alt="微信"></div>
</a>

                
        </div>
    </div>
</div>



<div class="card card-transparent">
    <div class="level post-navigation is-flex-wrap is-mobile">
        
        <div class="level-start">
            <a class="level level-item has-link-grey  article-nav-prev" href="/hexblog/2017/12/17/Java学习之深拷贝浅拷贝及对象拷贝的两种方式/">
                <i class="level-item fas fa-chevron-left"></i>
                <span class="level-item">Java学习之深拷贝浅拷贝及对象拷贝的两种方式</span>
            </a>
        </div>
        
        
        <div class="level-end">
            <a class="level level-item has-link-grey  article-nav-next" href="/hexblog/2017/09/08/ForkJoin-学习使用笔记/">
                <span class="level-item">ForkJoin 学习使用笔记</span>
                <i class="level-item fas fa-chevron-right"></i>
            </a>
        </div>
        
    </div>
</div>



<div class="card">
    <div class="card-content">
        <h3 class="title is-5 has-text-weight-normal">评论</h3>
        
<div id="comment-container"></div>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/gitalk@1.4.1/dist/gitalk.css">
<script src="https://cdn.jsdelivr.net/npm/gitalk@1.4.1/dist/gitalk.min.js"></script>
<script>
    var gitalk = new Gitalk({
        clientID: 'f4c5b85c7c1ceb8fbe2d',
        clientSecret: 'e8c365a05e6ab22272bee0b79ab27f69ff10a43a',
        id: 'b6ef048416f4a8224c5a5093f8da23d6',
        repo: 'hexblog',
        owner: 'liuyueyi',
        admin: "liuyueyi"
    })
    gitalk.render('comment-container')
</script>

    </div>
</div>
</div>
                




<div class="column is-4-tablet is-4-desktop is-3-widescreen  has-order-1 column-left ">
    
        
<div class="card widget">
    <div class="card-content card-info">
        <nav class="level">
            <div class="level-item has-text-centered">
                <div>
                    
                        <img class="image is-128x128 has-mb-6" src="/hexblog/images/avatar.jpg" alt="一灰灰Blog">
                    
                    
                    <p class="is-size-4 is-block">
                        一灰灰Blog
                    </p>
                    
                    
                    <p class="is-size-6 is-block">
                        Java，服务器后端开发
                    </p>
                    
                    
                    <p class="is-size-6 is-flex is-flex-center has-text-grey">
                        <i class="fas fa-map-marker-alt has-mr-7"></i>
                        <span>Wuhan, China</span>
                    </p>
                    
                </div>
            </div>
        </nav>
        <nav class="level is-mobile">
            <div class="level-item has-text-centered is-marginless">
                <div>
                    
                    <p class="heading">
                        文章
                    </p>
                    <a href="/hexblog/archives">
                    <p class="title has-text-weight-normal">
                        269
                    </p>
                    </a>
                </div>
            </div>
            <div class="level-item has-text-centered is-marginless">
                <div>
                    
                    <p class="heading">
                        分类
                    </p>
                    <a href="/hexblog/categories">
                        <p class="title has-text-weight-normal">
                            70
                        </p>
                    </a>
                </div>
            </div>
            <div class="level-item has-text-centered is-marginless">
                <div>
                
                    <p class="heading">
                        标签
                    </p>
                    <a href="/hexblog/tags">
                    <p class="title has-text-weight-normal">
                        74
                    </p>
                    </a>
                </div>
            </div>
        </nav>
        <div class="level">
            <a class="level-item button is-link is-rounded" href="https://github.com/liuyueyi" target="_blank">
                关注我</a>
        </div>
        
        
        <div class="level is-mobile">
            
            <a class="level-item button is-white is-marginless" target="_blank"
                title="Github" href="https://github.com/liuyueyi">
                
                <i class="fab fa-github"></i>
                
            </a>
            
            <a class="level-item button is-white is-marginless" target="_blank"
                title="Gitee" href="https://gitee.com/liuyueyi">
                
                <i class="fab fa-gg"></i>
                
            </a>
            
            <a class="level-item button is-white is-marginless" target="_blank"
                title="Weibo" href="https://weibo.com/p/1005052169825577/home">
                
                <i class="fab fa-weibo"></i>
                
            </a>
            
            <a class="level-item button is-white is-marginless" target="_blank"
                title="weixin" href="https://s10.mogucdn.com/mlcdn/c45406/171229_1cgld3igbelkbc70cd8af1j3809kb_150x150.jpg">
                
                <i class="fab fa-weixin"></i>
                
            </a>
            
            <a class="level-item button is-white is-marginless" target="_blank"
                title="RSS" href="/hexblog/atom.xml">
                
                <i class="fas fa-rss"></i>
                
            </a>
            
        </div>
        
    </div>
</div>
    
        
    
        

<div class="card widget">
    <div class="card-content">
        <div class="menu">
        <h3 class="menu-label">
            链接
        </h3>
        <ul class="menu-list">
        
            <li>
                <a class="level is-mobile" href="http://spring.hhui.top" target="_blank">
                    <span class="level-left">
                        <span class="level-item">SpringBlog</span>
                    </span>
                    <span class="level-right">
                        <span class="level-item tag">spring.hhui.top</span>
                    </span>
                </a>
            </li>
        
            <li>
                <a class="level is-mobile" href="https://github.com/liuyueyi" target="_blank">
                    <span class="level-left">
                        <span class="level-item">GitHub</span>
                    </span>
                    <span class="level-right">
                        <span class="level-item tag">github.com</span>
                    </span>
                </a>
            </li>
        
            <li>
                <a class="level is-mobile" href="https://zweb.hhui.top" target="_blank">
                    <span class="level-left">
                        <span class="level-item">多媒体工具小站</span>
                    </span>
                    <span class="level-right">
                        <span class="level-item tag">zweb.hhui.top</span>
                    </span>
                </a>
            </li>
        
            <li>
                <a class="level is-mobile" href="https://mweb.hhui.top" target="_blank">
                    <span class="level-left">
                        <span class="level-item">每日十首古诗词</span>
                    </span>
                    <span class="level-right">
                        <span class="level-item tag">mweb.hhui.top</span>
                    </span>
                </a>
            </li>
        
        </ul>
        </div>
    </div>
</div>


    
        
<div class="card widget">
    <div class="card-content">
        <h3 class="menu-label">
            最新文章
        </h3>
        
        <article class="media">
            
            <div class="media-content">
                <div class="content">
                    <div><time class="has-text-grey is-size-7 is-uppercase" datetime="2020-03-28T11:27:12.000Z">2020-03-28</time></div>
                    <a href="/hexblog/2020/03/28/200328-MongoDb系列教程九-文档-Document-查询基础篇/" class="has-link-black-ter is-size-6">200328-MongoDb系列教程九：文档 Document 查询基础篇</a>
                    <p class="is-size-7 is-uppercase">
                        <a class="has-link-grey -link" href="/hexblog/categories/DB/">DB</a> / <a class="has-link-grey -link" href="/hexblog/categories/DB/Mongo/">Mongo</a>
                    </p>
                </div>
            </div>
        </article>
        
        <article class="media">
            
            <div class="media-content">
                <div class="content">
                    <div><time class="has-text-grey is-size-7 is-uppercase" datetime="2020-03-27T03:04:36.000Z">2020-03-27</time></div>
                    <a href="/hexblog/2020/03/27/200327-MongoDb系列教程八-文档-Document-更新姿势/" class="has-link-black-ter is-size-6">200327-MongoDb系列教程八：文档 Document 更新姿势</a>
                    <p class="is-size-7 is-uppercase">
                        <a class="has-link-grey -link" href="/hexblog/categories/DB/">DB</a> / <a class="has-link-grey -link" href="/hexblog/categories/DB/Mongo/">Mongo</a>
                    </p>
                </div>
            </div>
        </article>
        
        <article class="media">
            
            <div class="media-content">
                <div class="content">
                    <div><time class="has-text-grey is-size-7 is-uppercase" datetime="2020-03-26T10:02:03.000Z">2020-03-26</time></div>
                    <a href="/hexblog/2020/03/26/200326-MongoDb系列教程七-文档-Document-删除姿势/" class="has-link-black-ter is-size-6">200326-MongoDb系列教程七：文档 Document 删除姿势</a>
                    <p class="is-size-7 is-uppercase">
                        <a class="has-link-grey -link" href="/hexblog/categories/DB/">DB</a> / <a class="has-link-grey -link" href="/hexblog/categories/DB/Mongo/">Mongo</a>
                    </p>
                </div>
            </div>
        </article>
        
        <article class="media">
            
            <div class="media-content">
                <div class="content">
                    <div><time class="has-text-grey is-size-7 is-uppercase" datetime="2020-03-26T09:04:06.000Z">2020-03-26</time></div>
                    <a href="/hexblog/2020/03/26/200326-MongoDb系列教程六-文档-Document-插入姿势/" class="has-link-black-ter is-size-6">200326-MongoDb系列教程六：文档 Document 插入姿势</a>
                    <p class="is-size-7 is-uppercase">
                        <a class="has-link-grey -link" href="/hexblog/categories/DB/">DB</a> / <a class="has-link-grey -link" href="/hexblog/categories/DB/Mongo/">Mongo</a>
                    </p>
                </div>
            </div>
        </article>
        
        <article class="media">
            
            <div class="media-content">
                <div class="content">
                    <div><time class="has-text-grey is-size-7 is-uppercase" datetime="2020-03-26T08:52:20.000Z">2020-03-26</time></div>
                    <a href="/hexblog/2020/03/26/200326-MongoDb系列教程五-集合-Collection/" class="has-link-black-ter is-size-6">200326-MongoDb系列教程五：集合 Collection</a>
                    <p class="is-size-7 is-uppercase">
                        <a class="has-link-grey -link" href="/hexblog/categories/DB/">DB</a> / <a class="has-link-grey -link" href="/hexblog/categories/DB/Mongo/">Mongo</a>
                    </p>
                </div>
            </div>
        </article>
        
    </div>
</div>

    
        
<div class="card widget">
    <div class="card-content">
        <h3 class="menu-label">
            标签云
        </h3>
        <a href="/hexblog/tags/Android/" style="font-size: 10px;">Android</a> <a href="/hexblog/tags/AutoCloseable/" style="font-size: 10px;">AutoCloseable</a> <a href="/hexblog/tags/BloomFilter/" style="font-size: 10px;">BloomFilter</a> <a href="/hexblog/tags/BugFix/" style="font-size: 10.63px;">BugFix</a> <a href="/hexblog/tags/Bugfix/" style="font-size: 10.63px;">Bugfix</a> <a href="/hexblog/tags/Docker/" style="font-size: 11.88px;">Docker</a> <a href="/hexblog/tags/FastJson/" style="font-size: 10px;">FastJson</a> <a href="/hexblog/tags/Git/" style="font-size: 11.25px;">Git</a> <a href="/hexblog/tags/Groovy/" style="font-size: 10px;">Groovy</a> <a href="/hexblog/tags/Guava/" style="font-size: 11.25px;">Guava</a> <a href="/hexblog/tags/HashMap/" style="font-size: 10px;">HashMap</a> <a href="/hexblog/tags/IO/" style="font-size: 10.63px;">IO</a> <a href="/hexblog/tags/ImageMagic/" style="font-size: 10.63px;">ImageMagic</a> <a href="/hexblog/tags/InfluxDB/" style="font-size: 16.88px;">InfluxDB</a> <a href="/hexblog/tags/InputStream/" style="font-size: 10px;">InputStream</a> <a href="/hexblog/tags/JDK/" style="font-size: 15px;">JDK</a> <a href="/hexblog/tags/JVM/" style="font-size: 11.25px;">JVM</a> <a href="/hexblog/tags/Java/" style="font-size: 20px;">Java</a> <a href="/hexblog/tags/JavaAgent/" style="font-size: 10.63px;">JavaAgent</a> <a href="/hexblog/tags/JavaWeb/" style="font-size: 10.63px;">JavaWeb</a> <a href="/hexblog/tags/Jquery/" style="font-size: 10px;">Jquery</a> <a href="/hexblog/tags/Linux/" style="font-size: 15px;">Linux</a> <a href="/hexblog/tags/List/" style="font-size: 10px;">List</a> <a href="/hexblog/tags/MD5/" style="font-size: 10px;">MD5</a> <a href="/hexblog/tags/Map/" style="font-size: 10px;">Map</a> <a href="/hexblog/tags/Maven/" style="font-size: 10px;">Maven</a> <a href="/hexblog/tags/Mongo/" style="font-size: 10.63px;">Mongo</a> <a href="/hexblog/tags/MongoDB/" style="font-size: 10px;">MongoDB</a> <a href="/hexblog/tags/MongoDb/" style="font-size: 14.38px;">MongoDb</a> <a href="/hexblog/tags/MySql/" style="font-size: 10.63px;">MySql</a> <a href="/hexblog/tags/Mybatis/" style="font-size: 10.63px;">Mybatis</a> <a href="/hexblog/tags/Mysql/" style="font-size: 16.25px;">Mysql</a> <a href="/hexblog/tags/Nginx/" style="font-size: 11.25px;">Nginx</a> <a href="/hexblog/tags/OGNL/" style="font-size: 11.25px;">OGNL</a> <a href="/hexblog/tags/ProtoStuff/" style="font-size: 10.63px;">ProtoStuff</a> <a href="/hexblog/tags/Python/" style="font-size: 19.38px;">Python</a> <a href="/hexblog/tags/QuickAlarm/" style="font-size: 10px;">QuickAlarm</a> <a href="/hexblog/tags/RabbitMQ/" style="font-size: 13.75px;">RabbitMQ</a> <a href="/hexblog/tags/ReactJS/" style="font-size: 10px;">ReactJS</a> <a href="/hexblog/tags/Redis/" style="font-size: 14.38px;">Redis</a> <a href="/hexblog/tags/Shell/" style="font-size: 15.63px;">Shell</a> <a href="/hexblog/tags/Socket/" style="font-size: 10px;">Socket</a> <a href="/hexblog/tags/Solr/" style="font-size: 10px;">Solr</a> <a href="/hexblog/tags/Spring/" style="font-size: 18.75px;">Spring</a> <a href="/hexblog/tags/SpringBoot/" style="font-size: 10px;">SpringBoot</a> <a href="/hexblog/tags/Vue/" style="font-size: 10px;">Vue</a> <a href="/hexblog/tags/WebSocket/" style="font-size: 10px;">WebSocket</a> <a href="/hexblog/tags/Yaml/" style="font-size: 10px;">Yaml</a> <a href="/hexblog/tags/css/" style="font-size: 11.25px;">css</a> <a href="/hexblog/tags/ffmpeg/" style="font-size: 10px;">ffmpeg</a> <a href="/hexblog/tags/gitalk/" style="font-size: 10px;">gitalk</a> <a href="/hexblog/tags/hexo/" style="font-size: 10px;">hexo</a> <a href="/hexblog/tags/jdk/" style="font-size: 10px;">jdk</a> <a href="/hexblog/tags/logger/" style="font-size: 10px;">logger</a> <a href="/hexblog/tags/markdown/" style="font-size: 10px;">markdown</a> <a href="/hexblog/tags/python/" style="font-size: 10px;">python</a> <a href="/hexblog/tags/time/" style="font-size: 10px;">time</a> <a href="/hexblog/tags/乱码/" style="font-size: 10px;">乱码</a> <a href="/hexblog/tags/二维码/" style="font-size: 10px;">二维码</a> <a href="/hexblog/tags/分库分表/" style="font-size: 10px;">分库分表</a> <a href="/hexblog/tags/反射/" style="font-size: 11.25px;">反射</a> <a href="/hexblog/tags/工具/" style="font-size: 12.5px;">工具</a> <a href="/hexblog/tags/并发/" style="font-size: 11.25px;">并发</a> <a href="/hexblog/tags/序列化/" style="font-size: 10px;">序列化</a> <a href="/hexblog/tags/手记/" style="font-size: 13.13px;">手记</a> <a href="/hexblog/tags/技术方案/" style="font-size: 18.13px;">技术方案</a> <a href="/hexblog/tags/指南/" style="font-size: 13.13px;">指南</a> <a href="/hexblog/tags/教程/" style="font-size: 17.5px;">教程</a> <a href="/hexblog/tags/方案设计/" style="font-size: 10px;">方案设计</a> <a href="/hexblog/tags/时区/" style="font-size: 10px;">时区</a> <a href="/hexblog/tags/时间窗口/" style="font-size: 11.25px;">时间窗口</a> <a href="/hexblog/tags/爬虫/" style="font-size: 12.5px;">爬虫</a> <a href="/hexblog/tags/问题记录/" style="font-size: 10px;">问题记录</a> <a href="/hexblog/tags/随笔/" style="font-size: 10px;">随笔</a>
    </div>
</div>

    
        <div class="card widget">
    <div class="card-content">
        <div class="menu">
            <h3 class="menu-label">
                标签
            </h3>
            <div class="field is-grouped is-grouped-multiline">
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Android/">
                        <span class="tag">Android</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/AutoCloseable/">
                        <span class="tag">AutoCloseable</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/BloomFilter/">
                        <span class="tag">BloomFilter</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/BugFix/">
                        <span class="tag">BugFix</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Bugfix/">
                        <span class="tag">Bugfix</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Docker/">
                        <span class="tag">Docker</span>
                        <span class="tag is-grey">4</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/FastJson/">
                        <span class="tag">FastJson</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Git/">
                        <span class="tag">Git</span>
                        <span class="tag is-grey">3</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Groovy/">
                        <span class="tag">Groovy</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Guava/">
                        <span class="tag">Guava</span>
                        <span class="tag is-grey">3</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/HashMap/">
                        <span class="tag">HashMap</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/IO/">
                        <span class="tag">IO</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/ImageMagic/">
                        <span class="tag">ImageMagic</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/InfluxDB/">
                        <span class="tag">InfluxDB</span>
                        <span class="tag is-grey">16</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/InputStream/">
                        <span class="tag">InputStream</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/JDK/">
                        <span class="tag">JDK</span>
                        <span class="tag is-grey">11</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/JVM/">
                        <span class="tag">JVM</span>
                        <span class="tag is-grey">3</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Java/">
                        <span class="tag">Java</span>
                        <span class="tag is-grey">59</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/JavaAgent/">
                        <span class="tag">JavaAgent</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/JavaWeb/">
                        <span class="tag">JavaWeb</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Jquery/">
                        <span class="tag">Jquery</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Linux/">
                        <span class="tag">Linux</span>
                        <span class="tag is-grey">11</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/List/">
                        <span class="tag">List</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/MD5/">
                        <span class="tag">MD5</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Map/">
                        <span class="tag">Map</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Maven/">
                        <span class="tag">Maven</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Mongo/">
                        <span class="tag">Mongo</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/MongoDB/">
                        <span class="tag">MongoDB</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/MongoDb/">
                        <span class="tag">MongoDb</span>
                        <span class="tag is-grey">9</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/MySql/">
                        <span class="tag">MySql</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Mybatis/">
                        <span class="tag">Mybatis</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Mysql/">
                        <span class="tag">Mysql</span>
                        <span class="tag is-grey">15</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Nginx/">
                        <span class="tag">Nginx</span>
                        <span class="tag is-grey">3</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/OGNL/">
                        <span class="tag">OGNL</span>
                        <span class="tag is-grey">3</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/ProtoStuff/">
                        <span class="tag">ProtoStuff</span>
                        <span class="tag is-grey">2</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Python/">
                        <span class="tag">Python</span>
                        <span class="tag is-grey">32</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/QuickAlarm/">
                        <span class="tag">QuickAlarm</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/RabbitMQ/">
                        <span class="tag">RabbitMQ</span>
                        <span class="tag is-grey">8</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/ReactJS/">
                        <span class="tag">ReactJS</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Redis/">
                        <span class="tag">Redis</span>
                        <span class="tag is-grey">9</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Shell/">
                        <span class="tag">Shell</span>
                        <span class="tag is-grey">13</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Socket/">
                        <span class="tag">Socket</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Solr/">
                        <span class="tag">Solr</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Spring/">
                        <span class="tag">Spring</span>
                        <span class="tag is-grey">25</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/SpringBoot/">
                        <span class="tag">SpringBoot</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Vue/">
                        <span class="tag">Vue</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/WebSocket/">
                        <span class="tag">WebSocket</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/Yaml/">
                        <span class="tag">Yaml</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/css/">
                        <span class="tag">css</span>
                        <span class="tag is-grey">3</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/ffmpeg/">
                        <span class="tag">ffmpeg</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/gitalk/">
                        <span class="tag">gitalk</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/hexo/">
                        <span class="tag">hexo</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/jdk/">
                        <span class="tag">jdk</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/logger/">
                        <span class="tag">logger</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/markdown/">
                        <span class="tag">markdown</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/python/">
                        <span class="tag">python</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/time/">
                        <span class="tag">time</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/乱码/">
                        <span class="tag">乱码</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/二维码/">
                        <span class="tag">二维码</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/分库分表/">
                        <span class="tag">分库分表</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/反射/">
                        <span class="tag">反射</span>
                        <span class="tag is-grey">3</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/工具/">
                        <span class="tag">工具</span>
                        <span class="tag is-grey">5</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/并发/">
                        <span class="tag">并发</span>
                        <span class="tag is-grey">3</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/序列化/">
                        <span class="tag">序列化</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/手记/">
                        <span class="tag">手记</span>
                        <span class="tag is-grey">6</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/技术方案/">
                        <span class="tag">技术方案</span>
                        <span class="tag is-grey">22</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/指南/">
                        <span class="tag">指南</span>
                        <span class="tag is-grey">6</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/教程/">
                        <span class="tag">教程</span>
                        <span class="tag is-grey">20</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/方案设计/">
                        <span class="tag">方案设计</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/时区/">
                        <span class="tag">时区</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/时间窗口/">
                        <span class="tag">时间窗口</span>
                        <span class="tag is-grey">3</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/爬虫/">
                        <span class="tag">爬虫</span>
                        <span class="tag is-grey">5</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/问题记录/">
                        <span class="tag">问题记录</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
                <div class="control">
                    <a class="tags has-addons" href="/hexblog/tags/随笔/">
                        <span class="tag">随笔</span>
                        <span class="tag is-grey">1</span>
                    </a>
                </div>
                
            </div>
        </div>
    </div>
</div>
    
    
        <div class="column-right-shadow is-hidden-widescreen ">
        
            
<div class="card widget">
    <div class="card-content">
        <div class="menu">
            <h3 class="menu-label">
                分类
            </h3>
            <ul class="menu-list">
            <li>
        <a class="level is-marginless" href="/hexblog/categories/DB/">
            <span class="level-start">
                <span class="level-item">DB</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">41</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/DB/InfluxDB/">
            <span class="level-start">
                <span class="level-item">InfluxDB</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">16</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/DB/Mongo/">
            <span class="level-start">
                <span class="level-item">Mongo</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">11</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/DB/Mysql/">
            <span class="level-start">
                <span class="level-item">Mysql</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">13</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/DB/分库分表/">
            <span class="level-start">
                <span class="level-item">分库分表</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/">
            <span class="level-start">
                <span class="level-item">Java</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">52</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/Agent/">
            <span class="level-start">
                <span class="level-item">Agent</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/Android/">
            <span class="level-start">
                <span class="level-item">Android</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/Bugfix/">
            <span class="level-start">
                <span class="level-item">Bugfix</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/IO/">
            <span class="level-start">
                <span class="level-item">IO</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/JDK/">
            <span class="level-start">
                <span class="level-item">JDK</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">22</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/JVM/">
            <span class="level-start">
                <span class="level-item">JVM</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">9</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/JavaWeb/">
            <span class="level-start">
                <span class="level-item">JavaWeb</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/其他/">
            <span class="level-start">
                <span class="level-item">其他</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">4</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/问题记录/">
            <span class="level-start">
                <span class="level-item">问题记录</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">6</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/">
            <span class="level-start">
                <span class="level-item">Python</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">33</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/Mongo/">
            <span class="level-start">
                <span class="level-item">Mongo</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/MySql/">
            <span class="level-start">
                <span class="level-item">MySql</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/教程/">
            <span class="level-start">
                <span class="level-item">教程</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">25</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/采坑记录/">
            <span class="level-start">
                <span class="level-item">采坑记录</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/项目/">
            <span class="level-start">
                <span class="level-item">项目</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/">
            <span class="level-start">
                <span class="level-item">Quick系列</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">30</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickAlarm/">
            <span class="level-start">
                <span class="level-item">QuickAlarm</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">8</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickCrawler/">
            <span class="level-start">
                <span class="level-item">QuickCrawler</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">5</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickFix/">
            <span class="level-start">
                <span class="level-item">QuickFix</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">6</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickMedia/">
            <span class="level-start">
                <span class="level-item">QuickMedia</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickSpi/">
            <span class="level-start">
                <span class="level-item">QuickSpi</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">4</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickTask/">
            <span class="level-start">
                <span class="level-item">QuickTask</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">5</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/">
            <span class="level-start">
                <span class="level-item">Shell</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">39</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/CMD/">
            <span class="level-start">
                <span class="level-item">CMD</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">18</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Docker/">
            <span class="level-start">
                <span class="level-item">Docker</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">4</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Git/">
            <span class="level-start">
                <span class="level-item">Git</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Maven/">
            <span class="level-start">
                <span class="level-item">Maven</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Ngins/">
            <span class="level-start">
                <span class="level-item">Ngins</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Nginx/">
            <span class="level-start">
                <span class="level-item">Nginx</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/环境搭建/">
            <span class="level-start">
                <span class="level-item">环境搭建</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">9</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/">
            <span class="level-start">
                <span class="level-item">前端</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">8</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/Chrome/">
            <span class="level-start">
                <span class="level-item">Chrome</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/Css/">
            <span class="level-start">
                <span class="level-item">Css</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/Jquery/">
            <span class="level-start">
                <span class="level-item">Jquery</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/ReactJS/">
            <span class="level-start">
                <span class="level-item">ReactJS</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/Vue/">
            <span class="level-start">
                <span class="level-item">Vue</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/工具/">
            <span class="level-start">
                <span class="level-item">工具</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">9</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/工具/工具类/">
            <span class="level-start">
                <span class="level-item">工具类</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">6</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/工具/插件系列/">
            <span class="level-start">
                <span class="level-item">插件系列</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/">
            <span class="level-start">
                <span class="level-item">开源</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">46</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Guava/">
            <span class="level-start">
                <span class="level-item">Guava</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Hexo/">
            <span class="level-start">
                <span class="level-item">Hexo</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Hystrix/">
            <span class="level-start">
                <span class="level-item">Hystrix</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Mybatis/">
            <span class="level-start">
                <span class="level-item">Mybatis</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/OGNL/">
            <span class="level-start">
                <span class="level-item">OGNL</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/RabbitMQ/">
            <span class="level-start">
                <span class="level-item">RabbitMQ</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">8</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Redis/">
            <span class="level-start">
                <span class="level-item">Redis</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Solr/">
            <span class="level-start">
                <span class="level-item">Solr</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Spring/">
            <span class="level-start">
                <span class="level-item">Spring</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">24</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Yaml/">
            <span class="level-start">
                <span class="level-item">Yaml</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/火花/">
            <span class="level-start">
                <span class="level-item">火花</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">4</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/随笔/">
            <span class="level-start">
                <span class="level-item">随笔</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">7</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/随笔/idea/">
            <span class="level-start">
                <span class="level-item">idea</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/随笔/吐槽/">
            <span class="level-start">
                <span class="level-item">吐槽</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li>
            </ul>
        </div>
    </div>
</div>
        
            <div class="card widget">
    <div class="card-content">
        <div class="menu">
        <h3 class="menu-label">
            归档
        </h3>
        <ul class="menu-list">
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2020/03/">
                <span class="level-start">
                    <span class="level-item">三月 2020</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">14</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2020/02/">
                <span class="level-start">
                    <span class="level-item">二月 2020</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">1</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2020/01/">
                <span class="level-start">
                    <span class="level-item">一月 2020</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">4</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/12/">
                <span class="level-start">
                    <span class="level-item">十二月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">5</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/11/">
                <span class="level-start">
                    <span class="level-item">十一月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">6</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/10/">
                <span class="level-start">
                    <span class="level-item">十月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">2</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/09/">
                <span class="level-start">
                    <span class="level-item">九月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">4</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/08/">
                <span class="level-start">
                    <span class="level-item">八月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">5</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/07/">
                <span class="level-start">
                    <span class="level-item">七月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">11</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/06/">
                <span class="level-start">
                    <span class="level-item">六月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">7</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/05/">
                <span class="level-start">
                    <span class="level-item">五月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">12</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/04/">
                <span class="level-start">
                    <span class="level-item">四月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">7</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/03/">
                <span class="level-start">
                    <span class="level-item">三月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">7</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/02/">
                <span class="level-start">
                    <span class="level-item">二月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">3</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/01/">
                <span class="level-start">
                    <span class="level-item">一月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">14</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/12/">
                <span class="level-start">
                    <span class="level-item">十二月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">8</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/11/">
                <span class="level-start">
                    <span class="level-item">十一月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">10</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/10/">
                <span class="level-start">
                    <span class="level-item">十月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">1</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/09/">
                <span class="level-start">
                    <span class="level-item">九月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">13</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/08/">
                <span class="level-start">
                    <span class="level-item">八月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">11</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/07/">
                <span class="level-start">
                    <span class="level-item">七月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">23</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/06/">
                <span class="level-start">
                    <span class="level-item">六月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">22</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/05/">
                <span class="level-start">
                    <span class="level-item">五月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">11</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/04/">
                <span class="level-start">
                    <span class="level-item">四月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">11</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/03/">
                <span class="level-start">
                    <span class="level-item">三月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">16</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/02/">
                <span class="level-start">
                    <span class="level-item">二月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">10</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/01/">
                <span class="level-start">
                    <span class="level-item">一月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">13</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/12/">
                <span class="level-start">
                    <span class="level-item">十二月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">6</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/09/">
                <span class="level-start">
                    <span class="level-item">九月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">1</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/08/">
                <span class="level-start">
                    <span class="level-item">八月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">3</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/07/">
                <span class="level-start">
                    <span class="level-item">七月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">2</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/06/">
                <span class="level-start">
                    <span class="level-item">六月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">2</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/05/">
                <span class="level-start">
                    <span class="level-item">五月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">4</span>
                </span>
            </a>
        </li>
        
        </ul>
        </div>
    </div>
</div>
        
        </div>
    
</div>

                




<div class="column is-4-tablet is-4-desktop is-2-widescreen is-hidden-touch is-hidden-desktop-only has-order-3 column-right ">
    
        
<div class="card widget">
    <div class="card-content">
        <div class="menu">
            <h3 class="menu-label">
                分类
            </h3>
            <ul class="menu-list">
            <li>
        <a class="level is-marginless" href="/hexblog/categories/DB/">
            <span class="level-start">
                <span class="level-item">DB</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">41</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/DB/InfluxDB/">
            <span class="level-start">
                <span class="level-item">InfluxDB</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">16</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/DB/Mongo/">
            <span class="level-start">
                <span class="level-item">Mongo</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">11</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/DB/Mysql/">
            <span class="level-start">
                <span class="level-item">Mysql</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">13</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/DB/分库分表/">
            <span class="level-start">
                <span class="level-item">分库分表</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/">
            <span class="level-start">
                <span class="level-item">Java</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">52</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/Agent/">
            <span class="level-start">
                <span class="level-item">Agent</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/Android/">
            <span class="level-start">
                <span class="level-item">Android</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/Bugfix/">
            <span class="level-start">
                <span class="level-item">Bugfix</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/IO/">
            <span class="level-start">
                <span class="level-item">IO</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/JDK/">
            <span class="level-start">
                <span class="level-item">JDK</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">22</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/JVM/">
            <span class="level-start">
                <span class="level-item">JVM</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">9</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/JavaWeb/">
            <span class="level-start">
                <span class="level-item">JavaWeb</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/其他/">
            <span class="level-start">
                <span class="level-item">其他</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">4</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Java/问题记录/">
            <span class="level-start">
                <span class="level-item">问题记录</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">6</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/">
            <span class="level-start">
                <span class="level-item">Python</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">33</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/Mongo/">
            <span class="level-start">
                <span class="level-item">Mongo</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/MySql/">
            <span class="level-start">
                <span class="level-item">MySql</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/教程/">
            <span class="level-start">
                <span class="level-item">教程</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">25</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/采坑记录/">
            <span class="level-start">
                <span class="level-item">采坑记录</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Python/项目/">
            <span class="level-start">
                <span class="level-item">项目</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/">
            <span class="level-start">
                <span class="level-item">Quick系列</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">30</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickAlarm/">
            <span class="level-start">
                <span class="level-item">QuickAlarm</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">8</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickCrawler/">
            <span class="level-start">
                <span class="level-item">QuickCrawler</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">5</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickFix/">
            <span class="level-start">
                <span class="level-item">QuickFix</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">6</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickMedia/">
            <span class="level-start">
                <span class="level-item">QuickMedia</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickSpi/">
            <span class="level-start">
                <span class="level-item">QuickSpi</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">4</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Quick系列/QuickTask/">
            <span class="level-start">
                <span class="level-item">QuickTask</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">5</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/">
            <span class="level-start">
                <span class="level-item">Shell</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">39</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/CMD/">
            <span class="level-start">
                <span class="level-item">CMD</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">18</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Docker/">
            <span class="level-start">
                <span class="level-item">Docker</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">4</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Git/">
            <span class="level-start">
                <span class="level-item">Git</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Maven/">
            <span class="level-start">
                <span class="level-item">Maven</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Ngins/">
            <span class="level-start">
                <span class="level-item">Ngins</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/Nginx/">
            <span class="level-start">
                <span class="level-item">Nginx</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/Shell/环境搭建/">
            <span class="level-start">
                <span class="level-item">环境搭建</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">9</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/">
            <span class="level-start">
                <span class="level-item">前端</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">8</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/Chrome/">
            <span class="level-start">
                <span class="level-item">Chrome</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/Css/">
            <span class="level-start">
                <span class="level-item">Css</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/Jquery/">
            <span class="level-start">
                <span class="level-item">Jquery</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/ReactJS/">
            <span class="level-start">
                <span class="level-item">ReactJS</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/前端/Vue/">
            <span class="level-start">
                <span class="level-item">Vue</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/工具/">
            <span class="level-start">
                <span class="level-item">工具</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">9</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/工具/工具类/">
            <span class="level-start">
                <span class="level-item">工具类</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">6</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/工具/插件系列/">
            <span class="level-start">
                <span class="level-item">插件系列</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/">
            <span class="level-start">
                <span class="level-item">开源</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">46</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Guava/">
            <span class="level-start">
                <span class="level-item">Guava</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Hexo/">
            <span class="level-start">
                <span class="level-item">Hexo</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Hystrix/">
            <span class="level-start">
                <span class="level-item">Hystrix</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Mybatis/">
            <span class="level-start">
                <span class="level-item">Mybatis</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">2</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/OGNL/">
            <span class="level-start">
                <span class="level-item">OGNL</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/RabbitMQ/">
            <span class="level-start">
                <span class="level-item">RabbitMQ</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">8</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Redis/">
            <span class="level-start">
                <span class="level-item">Redis</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Solr/">
            <span class="level-start">
                <span class="level-item">Solr</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Spring/">
            <span class="level-start">
                <span class="level-item">Spring</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">24</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/开源/Yaml/">
            <span class="level-start">
                <span class="level-item">Yaml</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li><li>
        <a class="level is-marginless" href="/hexblog/categories/火花/">
            <span class="level-start">
                <span class="level-item">火花</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">4</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/随笔/">
            <span class="level-start">
                <span class="level-item">随笔</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">7</span>
            </span>
        </a><ul><li>
        <a class="level is-marginless" href="/hexblog/categories/随笔/idea/">
            <span class="level-start">
                <span class="level-item">idea</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/hexblog/categories/随笔/吐槽/">
            <span class="level-start">
                <span class="level-item">吐槽</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li></ul></li>
            </ul>
        </div>
    </div>
</div>
    
        <div class="card widget">
    <div class="card-content">
        <div class="menu">
        <h3 class="menu-label">
            归档
        </h3>
        <ul class="menu-list">
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2020/03/">
                <span class="level-start">
                    <span class="level-item">三月 2020</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">14</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2020/02/">
                <span class="level-start">
                    <span class="level-item">二月 2020</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">1</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2020/01/">
                <span class="level-start">
                    <span class="level-item">一月 2020</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">4</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/12/">
                <span class="level-start">
                    <span class="level-item">十二月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">5</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/11/">
                <span class="level-start">
                    <span class="level-item">十一月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">6</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/10/">
                <span class="level-start">
                    <span class="level-item">十月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">2</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/09/">
                <span class="level-start">
                    <span class="level-item">九月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">4</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/08/">
                <span class="level-start">
                    <span class="level-item">八月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">5</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/07/">
                <span class="level-start">
                    <span class="level-item">七月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">11</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/06/">
                <span class="level-start">
                    <span class="level-item">六月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">7</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/05/">
                <span class="level-start">
                    <span class="level-item">五月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">12</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/04/">
                <span class="level-start">
                    <span class="level-item">四月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">7</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/03/">
                <span class="level-start">
                    <span class="level-item">三月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">7</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/02/">
                <span class="level-start">
                    <span class="level-item">二月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">3</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2019/01/">
                <span class="level-start">
                    <span class="level-item">一月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">14</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/12/">
                <span class="level-start">
                    <span class="level-item">十二月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">8</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/11/">
                <span class="level-start">
                    <span class="level-item">十一月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">10</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/10/">
                <span class="level-start">
                    <span class="level-item">十月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">1</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/09/">
                <span class="level-start">
                    <span class="level-item">九月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">13</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/08/">
                <span class="level-start">
                    <span class="level-item">八月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">11</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/07/">
                <span class="level-start">
                    <span class="level-item">七月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">23</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/06/">
                <span class="level-start">
                    <span class="level-item">六月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">22</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/05/">
                <span class="level-start">
                    <span class="level-item">五月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">11</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/04/">
                <span class="level-start">
                    <span class="level-item">四月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">11</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/03/">
                <span class="level-start">
                    <span class="level-item">三月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">16</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/02/">
                <span class="level-start">
                    <span class="level-item">二月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">10</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2018/01/">
                <span class="level-start">
                    <span class="level-item">一月 2018</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">13</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/12/">
                <span class="level-start">
                    <span class="level-item">十二月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">6</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/09/">
                <span class="level-start">
                    <span class="level-item">九月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">1</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/08/">
                <span class="level-start">
                    <span class="level-item">八月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">3</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/07/">
                <span class="level-start">
                    <span class="level-item">七月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">2</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/06/">
                <span class="level-start">
                    <span class="level-item">六月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">2</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/hexblog/archives/2017/05/">
                <span class="level-start">
                    <span class="level-item">五月 2017</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">4</span>
                </span>
            </a>
        </li>
        
        </ul>
        </div>
    </div>
</div>
    
    
</div>

            </div>
        </div>
    </section>
    <footer class="footer">
    <div class="container">
        <div class="level">
            <div class="level-start has-text-centered-mobile">
                <a class="footer-logo is-block has-mb-6" href="/hexblog/">
                
                    <img src="/hexblog/images/avatar.jpg" alt="图片合成支持的前世今生" height="28">
                
                </a>
                <p class="is-size-7">
                &copy; 2020 YiHui&nbsp;
                Powered by <a href="https://hexo.io/" target="_blank">Hexo</a> & <a
                        href="https://github.com/ppoffice/hexo-theme-icarus" target="_blank">Icarus</a>
                
                </p>
            </div>
            <div class="level-end">
            
                <div class="field has-addons is-flex-center-mobile has-mt-5-mobile is-flex-wrap is-flex-middle">
                
                
                <p class="control">
                    <a class="button is-white is-large" target="_blank" title="Download on GitHub" href="https://github.com/liuyueyi">
                        
                        <i class="fab fa-github"></i>
                        
                    </a>
                </p>
                
                <p class="control">
                    <a class="button is-white is-large" target="_blank" title="Chart in Weibo" href="https://weibo.com/p/1005052169825577/home">
                        
                        <i class="fab fa-weibo"></i>
                        
                    </a>
                </p>
                
                <p class="control">
                    <a class="button is-white is-large" target="_blank" title="Frends with me" href="https://s10.mogucdn.com/mlcdn/c45406/171229_1cgld3igbelkbc70cd8af1j3809kb_150x150.jpg">
                        
                        <i class="fab fa-weixin"></i>
                        
                    </a>
                </p>
                
                </div>
            
            </div>
        </div>
    </div>
    <hr/>
    <div id="foot-pannel">
        <div class="outer">
            <div class="foot-column">
                <!--关注我们-->
                <div class="widget-wrap widget-list">
                    <h3 class="widget-title">更多平台</h3>
                    <div class="widget">
                        <ul>
                            <li>
                                <a href="//blog.hhui.top/">一灰灰Blog</a>
                            </li>
                        
                            <li>
                                <a href="//juejin.im/user/5a2a4b095188252ae93adbbf/posts">掘金</a>
                            </li>
                        
                            <li>
                                <a href="//my.oschina.net/u/566591">开源中国</a>
                            </li>
                        
                            <li>
                                <a href="//blog.csdn.net/liuyueyi25">CSDN</a>
                            </li>
                        
                            <li>
                                <a href="//www.jianshu.com/u/5902ab08e670">简书</a>
                            </li>
                        
                            <li>
                                <a href="//cloud.tencent.com/developer/column/1847">云+</a>
                            </li>
                        
                            <li>
                                <a href="//www.toutiao.com/c/user/69862071663/#mid=1579653107239950">头条</a>
                            </li>
                        
                            <li>
                                <a href="//github.com/liuyueyi">GitHub</a>
                            </li>
                        
                            <li>
                                <a href="//gitee.com/liuyueyi">Gitee</a>
                            </li>
                            
                        </ul>
                    </div>
                </div>
            </div>
            <div class="foot-column">
                <!--联系合作-->
                <div class="widget-wrap widget-list">
                    <h3 class="widget-title">一灰灰Blog</h3>
                    <div class="widget">
                        <ul>
                            
                                <li>
                                    <a href="#">QQ : 3302797840</a>
                                </li>
                            
                                <li>
                                    <a href="#">微信 : liuyueyi25</a>
                                </li>
                            
                                <li>
                                    <a href="#">邮箱 : bangzewu@126.com</a>
                                </li>
                            
                                <li>
                                    <a href="#">微博 : 一灰灰blog</a>
                                </li>
                            
                        </ul>
                    </div>
                </div>
                <div class="widget-wrap widget-list">
                    <h3 class="widget-title">友情链接</h3>
                    <div class="widget">
                        <ul>
                            
                                <span class="label">
                                    <a target="_blank" href="//zweb.hhui.top">zweb多媒体工具页</a>
                                </span>
                            
                                <span class="label">
                                    <a target="_blank" href="//mweb.hhui.top">mweb古诗选</a>
                                </span>
                            
                        </ul>
                    </div>
                </div>
            </div>
            <div class="foot-column">
                <!--友情链接-->
                <div class="widget-wrap widget-list">
                    <h3 class="widget-title">知识星球</h3>
                    <div class="widget">
                        <img style="width: 200px;" src="/hexblog/imgs/info/xingqiu.png">
                    </div>
                </div>
                
            </div>
            <div class="foot-column">
                <div class="widget-wrap widget-list">
                    <h3 class="widget-title">公众号</h3>
                    <div class="widget">
                        <img style="width: 200px;" src="/hexblog/imgs/info/wx.jpg">
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div style="padding-top:20em">
        <hr/>
        <div id="foot-info">
            <span style="margin:4px;font-size:1em">
                &copy; 2020 <a target='_blank' href='https://github.com/liuyueyi'>一灰灰Blog</a> 版权所有 | <a href="http://www.beian.miit.gov.cn" target="_blank">鄂ICP备18017282号</a>
            </span>
            <br/>
            <span style="margin:4px;font-size:1em">
                <script type="text/javascript">document.write(unescape("%3Cspan id='cnzz_stat_icon_1278691600'%3E%3C/span%3E%3Cscript src='https://s9.cnzz.com/z_stat.php%3Fid%3D1278691600%26online%3D1%26show%3Dline' type='text/javascript'%3E%3C/script%3E"));</script>
            </span>
            <span style="margin:1em;font-size:1.4em">
                <label id="self_count_cnt"><br>本站总访量: <span class="visit_cnt">69330</span> | 总访问人次: <span class="visit_cnt">11586</span> | 恭喜您为第 <span class="visit_cnt">10840</span> 访问者</label>
            </span>
            <script src="/hexblog/js/count.js"></script>
        </div>
    </div>
</footer>
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/moment@2.22.2/min/moment-with-locales.min.js"></script>
<script>moment.locale("zh-CN");</script>


    
    
    
    <script src="/hexblog/js/animation.js"></script>
    

    
    
    
    <script src="https://cdn.jsdelivr.net/npm/lightgallery@1.6.8/dist/js/lightgallery.min.js" defer></script>
    <script src="https://cdn.jsdelivr.net/npm/justifiedGallery@3.7.0/dist/js/jquery.justifiedGallery.min.js" defer></script>
    <script src="/hexblog/js/gallery.js" defer></script>
    

    
    

<div id="outdated">
    <h6>Your browser is out-of-date!</h6>
    <p>Update your browser to view this website correctly. <a id="btnUpdateBrowser" href="http://outdatedbrowser.com/">Update
            my browser now </a></p>
    <p class="last"><a href="#" id="btnCloseUpdateBrowser" title="Close">&times;</a></p>
</div>
<script src="https://cdn.jsdelivr.net/npm/outdatedbrowser@1.1.5/outdatedbrowser/outdatedbrowser.min.js" defer></script>
<script>
    document.addEventListener("DOMContentLoaded", function () {
        outdatedBrowser({
            bgColor: '#f25648',
            color: '#ffffff',
            lowerThan: 'flex'
        });
    });
</script>


    
    
<script src="https://cdn.jsdelivr.net/npm/mathjax@2.7.5/unpacked/MathJax.js?config=TeX-MML-AM_CHTML" defer></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
    MathJax.Hub.Config({
        'HTML-CSS': {
            matchFontHeight: false
        },
        SVG: {
            matchFontHeight: false
        },
        CommonHTML: {
            matchFontHeight: false
        },
        tex2jax: {
            inlineMath: [
                ['$','$'],
                ['\\(','\\)']
            ]
        }
    });
});
</script>

    
    

<a id="back-to-top" title="回到顶端" href="javascript:;">
    <i class="fas fa-chevron-up"></i>
</a>
<script src="/hexblog/js/back-to-top.js" defer></script>


    
    

    
    
    
    

    
    
    
    
    
    <script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.4/dist/clipboard.min.js" defer></script>
    <script src="/hexblog/js/clipboard.js" defer></script>
    

    
    
    


<script src="/hexblog/js/main.js" defer></script>

    
    <div class="searchbox ins-search">
    <div class="searchbox-container ins-search-container">
        <div class="searchbox-input-wrapper">
            <input type="text" class="searchbox-input ins-search-input" placeholder="想要查找什么..." />
            <span class="searchbox-close ins-close ins-selectable"><i class="fa fa-times-circle"></i></span>
        </div>
        <div class="searchbox-result-wrapper ins-section-wrapper">
            <div class="ins-section-container"></div>
        </div>
    </div>
</div>
<script>
    (function (window) {
        var INSIGHT_CONFIG = {
            TRANSLATION: {
                POSTS: '文章',
                PAGES: '页面',
                CATEGORIES: '分类',
                TAGS: '标签',
                UNTITLED: '(无标题)',
            },
            CONTENT_URL: '/hexblog/content.json',
        };
        window.INSIGHT_CONFIG = INSIGHT_CONFIG;
    })(window);
</script>
<script src="/hexblog/js/insight.js" defer></script>
<link rel="stylesheet" href="/hexblog/css/search.css">
<link rel="stylesheet" href="/hexblog/css/insight.css">
    
</body>
</html>